C# 动态调用Web Service_c

其他范文 时间:2020-02-27 13:31:35 收藏本文下载本文
【www.daodoc.com - 其他范文】

C# 动态调用Web Service由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“c”。

整理,内容来源于网络及本人实践】

前面整理了一篇关于VS2008实现简单的WebService的文章,但里面的调用是静态的,当服务地址更改后,需要重新编译程序,对于很多应用来说是不现实的。本文介绍一下C#动态调用WebService的方法。

1.实现

写个叫WebServiceHelper的类

[csharp] view plaincopyprint?

1.namespace webhelp 2.{ 3.using System;4.using System.Net;5.using System.IO;6.using System.CodeDom;7.using Microsoft.CSharp;8.using System.CodeDom.Compiler;9.using System.Web.Services.Description;10.using System.Web.Services.Protocols;11.public cla WebServiceHelper 12.{ 13.#region InvokeWebService 14.15.public static object InvokeAndCallWebService(string url, string methodname, object[] args)16.{ 17.return WebServiceHelper.InvokeAndCallWebService(url, null, methodname, args);18.} 19.public static object InvokeAndCallWebService(string url,/* string @namespace, */string claname, string methodname, object[] args)20.{ 21.string @namespace = “EnterpriseServerBase.WebService.DynamicWebCalling”;22.if((claname == null)||(claname == “”))23.{ 24.claname = WebServiceHelper.GetWsClaName(url);25.} 26.27.try 28.{ 29.//获取WSDL 30.WebClient webClient = new WebClient();31.Stream stream = webClient.OpenRead(url + “?WSDL”);32.ServiceDescription description = ServiceDescription.Read(stream);33.ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();34.descriptionImporter.AddServiceDescription(description, “”, “”);35.CodeNamespace codeNamespace = new CodeNamespace(@namespace);36.37.//生成客户端代理类代码

38.CodeCompileUnit codeCompileUnit = new CodeCompileUnit();39.codeCompileUnit.Namespaces.Add(codeNamespace);40.descriptionImporter.Import(codeNamespace, codeCompileUnit);41.CSharpCodeProvider codeProvider = new CSharpCodeProvider();42.43.//设定编译参数

44.CompilerParameters compilerParameters = new CompilerParameters();45.compilerParameters.GenerateExecutable = false;46.compilerParameters.GenerateInMemory = true;47.compilerParameters.ReferencedAemblies.Add(“System.dll”);48.compilerParameters.ReferencedAemblies.Add(“System.XML.dll”);49.compilerParameters.ReferencedAemblies.Add(“System.Web.Services.dll”);50.compilerParameters.ReferencedAemblies.Add(“System.Data.dll”);51.52.//编译代理类

53.CompilerResults codeResult = codeProvider.CompileAemblyFromDom(compilerParameters, codeCompileUnit);54.if(true == codeResult.Errors.HasErrors)55.{ 56.System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();57.foreach(System.CodeDom.Compiler.CompilerError compileError in codeResult.Errors)58.{ 59.stringBuilder.Append(compileError.ToString());60.stringBuilder.Append(System.Environment.NewLine);61.} 62.throw new Exception(stringBuilder.ToString());63.} 64.65.//生成代理实例,并调用方法

66.System.Reflection.Aembly aembly = codeResult.CompiledAembly;67.Type @cla = aembly.GetType(@namespace + “.” + claname, true, true);68.object instance = Activator.CreateInstance(@cla);69.System.Reflection.MethodInfo methorInfo = @cla.GetMethod(methodname);70.71.return methorInfo.Invoke(instance, args);72.73.} 74.catch(Exception ex)75.{ 76.throw new Exception(ex.InnerException.Meage, new Exception(ex.InnerException.StackTrace));77.} 78.} 79.80.private static string GetWsClaName(string wsUrl)81.{ 82.string[] parts = wsUrl.Split('/');83.string[] pps = parts[parts.Length-1].Split('.');84.85.return pps[0];86.} 87.#endregion 88.} 89.}

2.注意

1.)若编译提示“命名空间“System.Web”中不存在类型或命名空间名称“Services”(是缺少程序集引用吗?)”,只需在解决方案资源管理器中添加对System.Web.Services的程序集引用即可。2.)不建议调用

[csharp] view plaincopyprint?

1.public static object InvokeAndCallWebService(string url, string methodname, object[] args)

即不指定类名,让程序由URL中分析出类名,因为不是所有服务的类名都放在URL的最后一个„/‟和„.‟中间的。

3.)@namespace不一定要取“EnterpriseServerBase.WebService.DynamicWebCalling”,从我的实验中,取任意@namespace,甚至@namespace是空串都能够正常运行。4.)网上有人说用这种方法调用Java写的Webservice时有问题,说是异常提示报的是无法获得相应空间里的类,有人说跟Java不要命名空间有关。我特意请同学帮我做一个java 的webservice(因为我不会java),实验证明这种方法并没有什么问题,我猜测报异常可能是因为没有指定类名,而是代码根据url分析类名,或者有可能是服务返回类型是一些复杂类型的值,建议返回类型最好是string或int之类的。

5.)在这种方法中url、命名空间、类名、函数名都是字符串,可以根据需要进行赋值。

3.调用

注意到上面实现的InvokeAndCallWebService是个静态函数,所以想利用WebServiceHelper调用Webservice方法如下。

[csharp] view plaincopyprint?

1.string url = “http://192.168.0.113/NM2SMARTB/INM2SmartSoap11Binding.asmx”;2.string[] args = new string[1];3.args[0] = “hello”;4.object result = webhelp.WebServiceHelper.InvokeAndCallWebService(url, “Nm2Smart”, “getDevices”, args);4.变化 上面的WebServiceHelper利用静态方法实现动态调用WebService,但是仍存在一个问题,就是每次函数InvokeAndCallWebService都要重新获取服务、生成代理等一系列过程,这样子的效率很低。所以可以对WebServiceHelper稍作修改,在服务没更改的的时候,只生成一次代理,可以多次调用其中的函数。大部分代码仍和上面一样。只是将服务实例化代码和调用分开,将InvokeAndCallWebService中的局部变量instance和@cla变为类成员变量。如此只要声明一个WebServiceHelper对象,就可以只生成一次代理,多次调用函数,直到必要的时候再重新生成代理实例。当然此时函数已不是静态函数。

[csharp] view plaincopyprint?

1.namespace webhelp 2.{ 3.using System;4.using System.Net;5.using System.IO;6.using System.CodeDom;7.using Microsoft.CSharp;8.using System.CodeDom.Compiler;9.using System.Web.Services.Description;10.using System.Web.Services.Protocols;11.public cla WebServiceHelper 12.{ 13.#region InvokeWebService 14.object instance;//将原来函数内的局部变量变为类成员 15.Type @cla;//将原来函数内的局部变量变为类成员 16.17.public void InvokeWebService(string url,/* string @namespace,*/ string claname)18.{ 19.string @namespace = “EnterpriseServerBase.WebService.DynamicWebCalling”;20.if((claname == null)||(claname == “”))21.{ 22.claname = WebServiceHelper.GetWsClaName(url);23.} 24.25.try 26.{ 27.//获取WSDL 28.WebClient webClient = new WebClient();29.Stream stream = webClient.OpenRead(url + “?WSDL”);30.ServiceDescription description = ServiceDescription.Read(stream);31.ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();32.descriptionImporter.AddServiceDescription(description, “”, “”);33.CodeNamespace codeNamespace = new CodeNamespace(@namespace);34.35.//生成客户端代理类代码

36.CodeCompileUnit codeCompileUnit = new CodeCompileUnit();37.codeCompileUnit.Namespaces.Add(codeNamespace);38.descriptionImporter.Import(codeNamespace, codeCompileUnit);39.CSharpCodeProvider codeProvider = new CSharpCodeProvider();40.41.//设定编译参数

42.CompilerParameters compilerParameters = new CompilerParameters();43.compilerParameters.GenerateExecutable = false;44.compilerParameters.GenerateInMemory = true;45.compilerParameters.ReferencedAemblies.Add(“System.dll”);46.compilerParameters.ReferencedAemblies.Add(“System.XML.dll”);47.compilerParameters.ReferencedAemblies.Add(“System.Web.Services.dll”);48.compilerParameters.ReferencedAemblies.Add(“System.Data.dll”);49.50.//编译代理类

51.CompilerResults codeResult = codeProvider.CompileAemblyFromDom(compilerParameters, codeCompileUnit);52.if(true == codeResult.Errors.HasErrors)53.{ 54.System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();55.foreach(System.CodeDom.Compiler.CompilerError compileError in codeResult.Errors)56.{ 57.stringBuilder.Append(compileError.ToString());58.stringBuilder.Append(System.Environment.NewLine);59.} 60.throw new Exception(stringBuilder.ToString());61.} 62.63.//生成代理实例

64.System.Reflection.Aembly aembly = codeResult.CompiledAembly;65.@cla = aembly.GetType(@namespace + “.” + claname, true, true);66.instance = Activator.CreateInstance(@cla);67.// return instance;68.} 69.catch(Exception ex)70.{ 71.throw new Exception(ex.InnerException.Meage, new Exception(ex.InnerException.StackTrace));72.} 73.} 74.public object CallService(string methodname, object[] args)//调用方法与生成代理实例分开 75.{ 76.try 77.{ 78.System.Reflection.MethodInfo methorInfo = @cla.GetMethod(methodname);79.return methorInfo.Invoke(instance, args);80.} 81.catch(System.Exception ex)82.{ 83.throw ex;84.} 85.} 86.87.#endregion 88.} 89.} 5.疑问 作为一个新手,虽然知道动态调用的方法,但是其中一些东西还不是很了解,就像某老师说的“知其然不知其所以然”,希望能够有热心朋友帮我解答。比如@namespace是指什么的命名空间?我的想法是,这应该是指生成代理类所在的命名空间,但是如果我多次创建同一个代理,那不是在同一命名空间中存在多个同名类?却没有报错。或是我故意指定@namespace为webhelp,并在webhelp中定义一个同名的类,程序也是正常的。这里这个命名空间的作用是什么呢?即使指定命名空间为空字符串,仍是没有问题的。

ORACLE9i动态SQL调用方法心得

ORACLE9i动态SQL调用方法心得一、执行动态函数 --返回值OUT_CS:=0; --参数IN_CS1:=100;IN_CS2:=150; --自定义函数名称FUN_01();NAME:='01' V_SQL := 'BEGIN :1:=FUN_'......

Oracle调用外部动态库的设置方法

oracle在调用外部动态库时需要设置EXTPROC_DLLS 10G设置方法修改ORA_HOME/NETWORK/ADMIN/listener.ora SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = PLSEx......

用C#与XML创建动态分层菜单

从在复杂的B2B交易中的交换数据到为应用程序提供配置文件结构,XML在许多方面大显身手!由于XML不断地获得软件的支持,我们完全能够预见:XML的应用将不断增加。本文就介绍这样一种......

webService基础总结

 WebService是一种跨编程语言和跨操作系统平台的远程调用技术 所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然!跨操......

WebService优缺点[版]

Web服务的优缺点分析当前WebService是一个热门话题。但是,WebService究竟是什么?,WebService有什么优点和缺点,什么情况下应该用WebService?什么情况下不应该用WebService?是需要......

下载C# 动态调用Web Serviceword格式文档
下载C# 动态调用Web Service.doc
将本文档下载到自己电脑,方便修改和收藏。
点此处下载文档

文档为doc格式

相关专题 c 动态 web Service
热门文章
点击下载本文