大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > C# 动态调用WebService

C# 动态调用WebService

关键词:动态调用WebServiceC#  阅读(1501) 赞(18)

[摘要]本文是对C# 动态调用WebService的讲解,对学习C#编程技术有所帮助,与大家分享。

动态调用webservice,就可以不用添加web引用了,上线的话也只是需要改一下wsdl地址就可以了

1.动态调用的方法:

C#代码
  1. ///<summary>
  2. ///动态webservice调用
  3. ///</summary>
  4. ///<returns>string</returns>
  5. publicstringwsTest()
  6. {
  7. stringurl="http://localhost:8080/myWebserviceTest/services/myServices?wsdl";//wsdl地址
  8. stringname="wsTest";//javaWebService开放的接口
  9. WebServiceProxywsd=newWebServiceProxy(url,name);
  10. string[]str={"测试c#调用java的webService","HelloWebService"};
  11. stringsuc=(string)wsd.ExecuteQuery(name,str);
  12. returnsuc;
  13. }



2.动态调用具体类:

C#代码 收藏代码
  1. usingSystem;
  2. usingSystem.Collections;
  3. usingSystem.ComponentModel;
  4. usingSystem.Data;
  5. usingSystem.Linq;
  6. usingSystem.Web;
  7. usingSystem.Web.Services;
  8. usingSystem.Web.Services.Protocols;
  9. usingSystem.Xml.Linq;
  10. usingSystem.IO;
  11. usingSystem.Net;
  12. usingSystem.CodeDom;
  13. usingSystem.CodeDom.Compiler;
  14. usingSystem.Web.Services.Description;
  15. usingSystem.Xml.Serialization;
  16. usingSystem.Web.Services.Discovery;
  17. usingSystem.Xml.Schema;
  18. usingSystem.Text;
  19. usingSystem.Security.Cryptography;
  20. usingSystem.Reflection;
  21. usingSystem.Collections.Generic;
  22. usingSystem.Xml;
  23. namespaceTPSVService
  24. {
  25. ///<summary>
  26. ///WebServiceProxy的摘要说明
  27. ///</summary>
  28. [WebService(Namespace="http://tempuri.org/")]
  29. [WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
  30. [ToolboxItem(false)]
  31. //若要允许使用ASP.NETAJAX从脚本中调用此Web服务,请取消对下行的注释。
  32. //[System.Web.Script.Services.ScriptService]
  33. publicclassWebServiceProxy:System.Web.Services.WebService
  34. {
  35. #region私有变量和属性定义
  36. ///<summary>
  37. ///web服务地址
  38. ///</summary>
  39. privatestring_wsdlUrl=string.Empty;
  40. ///<summary>
  41. ///web服务名称
  42. ///</summary>
  43. privatestring_wsdlName=string.Empty;
  44. ///<summary>
  45. ///代理类命名空间
  46. ///</summary>
  47. privatestring_wsdlNamespace="FrameWork.WebService.DynamicWebServiceCalling.{0}";
  48. ///<summary>
  49. ///代理类类型名称
  50. ///</summary>
  51. privateType_typeName=null;
  52. ///<summary>
  53. ///程序集名称
  54. ///</summary>
  55. privatestring_assName=string.Empty;
  56. ///<summary>
  57. ///代理类所在程序集路径
  58. ///</summary>
  59. privatestring_assPath=string.Empty;
  60. ///<summary>
  61. ///代理类的实例
  62. ///</summary>
  63. privateobject_instance=null;
  64. ///<summary>
  65. ///代理类的实例
  66. ///</summary>
  67. privateobjectInstance
  68. {
  69. get
  70. {
  71. if(_instance==null)
  72. {
  73. _instance=Activator.CreateInstance(_typeName);
  74. return_instance;
  75. }
  76. else
  77. return_instance;
  78. }
  79. }
  80. #endregion
  81. #region构造函数
  82. publicWebServiceProxy(stringwsdlUrl)
  83. {
  84. this._wsdlUrl=wsdlUrl;
  85. stringwsdlName=WebServiceProxy.getWsclassName(wsdlUrl);
  86. this._wsdlName=wsdlName;
  87. this._assName=string.Format(_wsdlNamespace,wsdlName);
  88. this._assPath=Path.GetTempPath()+this._assName+getMd5Sum(this._wsdlUrl)+".dll";
  89. this.CreateServiceAssembly();
  90. }
  91. publicWebServiceProxy(stringwsdlUrl,stringwsdlName)
  92. {
  93. this._wsdlUrl=wsdlUrl;
  94. this._wsdlName=wsdlName;
  95. this._assName=string.Format(_wsdlNamespace,wsdlName);
  96. this._assPath=Path.GetTempPath()+this._assName+getMd5Sum(this._wsdlUrl)+".dll";
  97. this.CreateServiceAssembly();
  98. }
  99. #endregion
  100. #region得到WSDL信息,生成本地代理类并编译为DLL,构造函数调用,类生成时加载
  101. ///<summary>
  102. ///得到WSDL信息,生成本地代理类并编译为DLL
  103. ///</summary>
  104. privatevoidCreateServiceAssembly()
  105. {
  106. if(this.checkCache())
  107. {
  108. this.initTypeName();
  109. return;
  110. }
  111. if(string.IsNullOrEmpty(this._wsdlUrl))
  112. {
  113. return;
  114. }
  115. try
  116. {
  117. //使用WebClient下载WSDL信息
  118. WebClientweb=newWebClient();
  119. Streamstream=web.OpenRead(this._wsdlUrl);
  120. ServiceDescriptiondescription=ServiceDescription.Read(stream);//创建和格式化WSDL文档
  121. ServiceDescriptionImporterimporter=newServiceDescriptionImporter();//创建客户端代理代理类
  122. importer.ProtocolName="Soap";
  123. importer.Style=ServiceDescriptionImportStyle.Client;//生成客户端代理
  124. importer.CodeGenerationOptions=CodeGenerationOptions.GenerateProperties|CodeGenerationOptions.GenerateNewAsync;
  125. importer.AddServiceDescription(description,null,null);//添加WSDL文档
  126. //使用CodeDom编译客户端代理类
  127. CodeNamespacenmspace=newCodeNamespace(_assName);//为代理类添加命名空间
  128. CodeCompileUnitunit=newCodeCompileUnit();
  129. unit.Namespaces.Add(nmspace);
  130. this.checkForImports(this._wsdlUrl,importer);
  131. ServiceDescriptionImportWarningswarning=importer.Import(nmspace,unit);
  132. CodeDomProviderprovider=CodeDomProvider.CreateProvider("CSharp");
  133. CompilerParametersparameter=newCompilerParameters();
  134. parameter.ReferencedAssemblies.Add("System.dll");
  135. parameter.ReferencedAssemblies.Add("System.XML.dll");
  136. parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
  137. parameter.ReferencedAssemblies.Add("System.Data.dll");
  138. parameter.GenerateExecutable=false;
  139. parameter.GenerateInMemory=false;
  140. parameter.IncludeDebugInformation=false;
  141. CompilerResultsresult=provider.CompileAssemblyFromDom(parameter,unit);
  142. provider.Dispose();
  143. if(result.Errors.HasErrors)
  144. {
  145. stringerrors=string.Format(@"编译错误:{0}错误!",result.Errors.Count);
  146. foreach(CompilerErrorerrorinresult.Errors)
  147. {
  148. errors+=error.ErrorText;
  149. }
  150. thrownewException(errors);
  151. }
  152. this.copyTempAssembly(result.PathToAssembly);
  153. this.initTypeName();
  154. }
  155. catch(Exceptione)
  156. {
  157. thrownewException(e.Message);
  158. }
  159. }
  160. #endregion
  161. #region执行Web服务方法
  162. ///<summary>
  163. ///执行代理类指定方法,有返回值
  164. ///</summary>
  165. ///<paramname="methodName">方法名称</param>
  166. ///<paramname="param">参数</param>
  167. ///<returns>object</returns>
  168. publicobjectExecuteQuery(stringmethodName,object[]param)
  169. {
  170. objectrtnObj=null;
  171. string[]args=newstring[2];
  172. List<string>list=newList<string>();
  173. List<string>list1=newList<string>();
  174. List<string>list2=newList<string>();
  175. object[]obj=newobject[3];
  176. try
  177. {
  178. if(this._typeName==null)
  179. {
  180. //记录Web服务访问类名错误日志代码位置
  181. thrownewTypeLoadException("Web服务访问类名【"+this._wsdlName+"】不正确,请检查!");
  182. }
  183. //调用方法
  184. MethodInfomi=this._typeName.GetMethod(methodName);
  185. if(mi==null)
  186. {
  187. //记录Web服务方法名错误日志代码位置
  188. thrownewTypeLoadException("Web服务访问方法名【"+methodName+"】不正确,请检查!");
  189. }
  190. try
  191. {
  192. if(param==null)
  193. rtnObj=mi.Invoke(Instance,null);
  194. else{
  195. list.Add("Hello");
  196. list.Add("WebService");
  197. list.Add("!");
  198. list1.Add("I");
  199. list1.Add("am");
  200. list1.Add("test");
  201. list2.Add("do");
  202. list2.Add("it");
  203. list2.Add("now");
  204. obj[0]=list;
  205. obj[1]=list1;
  206. obj[2]=list2;
  207. rtnObj=mi.Invoke(Instance,newobject[]{obj});
  208. //rtnObj=mi.Invoke(Instance,newobject[]{param});
  209. }
  210. }
  211. catch(TypeLoadExceptiontle)
  212. {
  213. //记录Web服务方法参数个数错误日志代码位置
  214. thrownewTypeLoadException("Web服务访问方法【"+methodName+"】参数个数不正确,请检查!",newTypeLoadException(tle.StackTrace));
  215. }
  216. }
  217. catch(Exceptionex)
  218. {
  219. thrownewException(ex.Message,newException(ex.StackTrace));
  220. }
  221. returnrtnObj;
  222. }
  223. ///<summary>
  224. ///执行代理类指定方法,无返回值
  225. ///</summary>
  226. ///<paramname="methodName">方法名称</param>
  227. ///<paramname="param">参数</param>
  228. publicvoidExecuteNoQuery(stringmethodName,object[]param)
  229. {
  230. try
  231. {
  232. if(this._typeName==null)
  233. {
  234. //记录Web服务访问类名错误日志代码位置
  235. thrownewTypeLoadException("Web服务访问类名【"+this._wsdlName+"】不正确,请检查!");
  236. }
  237. //调用方法
  238. MethodInfomi=this._typeName.GetMethod(methodName);
  239. if(mi==null)
  240. {
  241. //记录Web服务方法名错误日志代码位置
  242. thrownewTypeLoadException("Web服务访问方法名【"+methodName+"】不正确,请检查!");
  243. }
  244. try
  245. {
  246. if(param==null)
  247. mi.Invoke(Instance,null);
  248. else
  249. mi.Invoke(Instance,param);
  250. }
  251. catch(TypeLoadExceptiontle)
  252. {
  253. //记录Web服务方法参数个数错误日志代码位置
  254. thrownewTypeLoadException("Web服务访问方法【"+methodName+"】参数个数不正确,请检查!",newTypeLoadException(tle.StackTrace));
  255. }
  256. }
  257. catch(Exceptionex)
  258. {
  259. thrownewException(ex.Message,newException(ex.StackTrace));
  260. }
  261. }
  262. #endregion
  263. #region私有方法
  264. ///<summary>
  265. ///得到代理类类型名称
  266. ///</summary>
  267. privatevoidinitTypeName()
  268. {
  269. AssemblyserviceAsm=Assembly.LoadFrom(this._assPath);
  270. Type[]types=serviceAsm.GetTypes();
  271. stringobjTypeName="";
  272. foreach(Typetintypes)
  273. {
  274. if(t.BaseType==typeof(SoapHttpClientProtocol))
  275. {
  276. objTypeName=t.Name;
  277. break;
  278. }
  279. }
  280. _typeName=serviceAsm.GetType(this._assName+"."+objTypeName);
  281. }
  282. ///<summary>
  283. ///根据webservice文档架构向代理类添加ServiceDescription和XmlSchema
  284. ///</summary>
  285. ///<paramname="baseWSDLUrl">web服务地址</param>
  286. ///<paramname="importer">代理类</param>
  287. privatevoidcheckForImports(stringbaseWsdlUrl,ServiceDescriptionImporterimporter)
  288. {
  289. DiscoveryClientProtocoldcp=newDiscoveryClientProtocol();
  290. dcp.DiscoverAny(baseWsdlUrl);
  291. dcp.ResolveAll();
  292. foreach(objectosdindcp.Documents.Values)
  293. {
  294. if(osdisServiceDescription)importer.AddServiceDescription((ServiceDescription)osd,null,null);;
  295. if(osdisXmlSchema)importer.Schemas.Add((XmlSchema)osd);
  296. }
  297. }
  298. ///<summary>
  299. ///复制程序集到指定路径
  300. ///</summary>
  301. ///<paramname="pathToAssembly">程序集路径</param>
  302. privatevoidcopyTempAssembly(stringpathToAssembly)
  303. {
  304. File.Copy(pathToAssembly,this._assPath);
  305. }
  306. privatestringgetMd5Sum(stringstr)
  307. {
  308. Encoderenc=System.Text.Encoding.Unicode.GetEncoder();
  309. byte[]unicodeText=newbyte[str.Length*2];
  310. enc.GetBytes(str.ToCharArray(),0,str.Length,unicodeText,0,true);
  311. MD5md5=newMD5CryptoServiceProvider();
  312. byte[]result=md5.ComputeHash(unicodeText);
  313. StringBuildersb=newStringBuilder();
  314. for(inti=0;i<result.Length;i++)
  315. {
  316. sb.Append(result[i].ToString("X2"));
  317. }
  318. returnsb.ToString();
  319. }
  320. ///<summary>
  321. ///是否已经存在该程序集
  322. ///</summary>
  323. ///<returns>false:不存在该程序集,true:已经存在该程序集</returns>
  324. privateboolcheckCache()
  325. {
  326. if(File.Exists(this._assPath))
  327. {
  328. returntrue;
  329. }
  330. returnfalse;
  331. }
  332. //私有方法,默认取url入口的文件名为类名
  333. privatestaticstringgetWsclassName(stringwsdlUrl)
  334. {
  335. string[]parts=wsdlUrl.Split('/');
  336. string[]pps=parts[parts.Length-1].Split('.');
  337. returnpps[0];
  338. }
  339. #endregion
  340. }
  341. }


java接口可以用Object[]类型接收参数

创建个c#的webservice应用,可以运行本示例



相关评论