C#动态调用webservice
转自:http://www.cnblogs.com/langhua/p/3344784.html#commentform
在做多个系统集成的时候,由于各系统厂商采用不同的架构,在项目实施前期,各业务对业务理解不够深入,系统接口可能会有较多变化,
在此背景下,动态调用webserivce就变得灵活了,降低了系统集成的耦合度。
下面介绍动态调用的具体步骤:
具体步骤:
1. 从目标 URL 下载 WSDL 数据。
2. 使用 ServiceDescription 创建和格式化 WSDL 文档文件。
3. 使用 ServiceDescriptionImporter 创建客户端代理类。
4. 使用 CodeDom 动态创建客户端代理类程序集。
5. 利用反射调用相关 WebService 方法。
其实与手工创建添加引用步骤一样,只是在这里把手动变成了自动而已,动态生成代理类,利用反射动态调用了方法。
下面看代码:代码也是摘自博友的,只是作了一些小的修改,
1 /// < summary> 2 /// 动态调用web服务 3 /// < /summary> 4 /// < param name="url">WSDL服务地址< /param> 5 /// < param name="classname">类名< /param> 6 /// < param name="methodname">方法名< /param> 7 /// < param name="args">参数< /param> 8 /// < returns>< /returns> 9 public object InvokeWebService(string url, string classname, string methodname, object[] args) 10 { 11 string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; 12 if ((classname == null) || (classname == "")) 13 { 14 classname = CommonServiceHelper.GetWsClassName(url); 15 } 16 try 17 { 18 //获取WSDL 19 WebClient wc = new WebClient(); 20 Stream stream = wc.OpenRead(url + "?WSDL"); 21 ServiceDescription sd = ServiceDescription.Read(stream); 22 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); 23 sdi.AddServiceDescription(sd, "", ""); 24 CodeNamespace cn = new CodeNamespace(@namespace); 25 //生成客户端代理类代码 26 CodeCompileUnit ccu = new CodeCompileUnit(); 27 ccu.Namespaces.Add(cn); 28 sdi.Import(cn, ccu); 29 CSharpCodeProvider icc = new CSharpCodeProvider(); 30 //设定编译参数 31 CompilerParameters cplist = new CompilerParameters(); 32 cplist.GenerateExecutable = false; 33 cplist.GenerateInMemory = true; 34 cplist.ReferencedAssemblies.Add("System.dll"); 35 cplist.ReferencedAssemblies.Add("System.XML.dll"); 36 cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); 37 cplist.ReferencedAssemblies.Add("System.Data.dll"); 38 //编译代理类 39 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); 40 if (true == cr.Errors.HasErrors) 41 { 42 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 43 foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) 44 { 45 sb.Append(ce.ToString()); 46 sb.Append(System.Environment.NewLine); 47 } 48 throw new Exception(sb.ToString()); 49 } 50 //生成代理实例,并调用方法 51 System.Reflection.Assembly assembly = cr.CompiledAssembly; 52 Type t = assembly.GetType(@namespace + "." + classname, true, true); 53 object obj = Activator.CreateInstance(t); 54 System.Reflection.MethodInfo mi = t.GetMethod(methodname); 55 return mi.Invoke(obj, args); 56 /* 57 * PropertyInfo propertyInfo = type.GetProperty(propertyname); 58 * return propertyInfo.GetValue(obj, null); 59 * */ 60 } 61 catch (Exception ex) 62 { 63 throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace)); 64 } 65 } 66 private static string GetWsClassName(string wsUrl) 67 { 68 string[] parts = wsUrl.Split('/'); 69 string[] pps = parts[parts.Length - 1].Split('.'); 70 return pps[0]; 71 }
单元测试代码:
1 /// <summary> 2 ///InvokeWebService 的测试 3 ///</summary> 4 [TestMethod()] 5 public void InvokeWebServiceTest() 6 { 7 CommonServiceHelper target = new CommonServiceHelper(); // TODO: 初始化为适当的值 8 string url = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx"; // TODO: 初始化为适当的值 9 string classname = string.Empty; // TODO: 初始化为适当的值 10 string methodname = "getWeather"; // TODO: 初始化为适当的值 11 string[] a = new string[2] { "bj","" }; 12 object[] args = a; // TODO: 初始化为适当的值 13 object expected = null; // TODO: 初始化为适当的值 14 object actual; 15 actual = target.InvokeWebService(url, classname, methodname, args); 16 Assert.AreEqual(expected, actual); 17 Assert.Inconclusive("验证此测试方法的正确性。"); 18 }
作者:浪花一朵朵
出处:http://www.cnblogs.com/langhua/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。