C#动态库调用webservice
2023-07-22 12:17 bgbing 阅读(19) 评论(0) 编辑 收藏 举报1.c#调用一外部webservice时,对方能收到数据包,缺收不到正确数据,报莫名错误。对方也不知道原因。
只能采用动态调用方式。
采用如下类:
1 public class WebserviceHelper 2 { 3 /// <summary> 4 /// 动态调用web服务 5 /// </summary> 6 /// <param name="url">web服务地址</param> 7 /// <param name="classname">类名</param> 8 /// <param name="methodname">方法名</param> 9 /// <param name="args">参数数组</param> 10 /// <returns>返回结果</returns> 11 public static object InvokeWebService(string url, string namespaceName, string classname, string methodname, object[] args) 12 { 13 string @namespace = namespaceName; 14 if (namespaceName == null) 15 { 16 @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; 17 } 18 if ((classname == null) || (classname == "")) 19 { 20 classname = WebserviceHelper.GetWsClassName(url); 21 } 22 try 23 { 24 //返回首次编译的对象 25 object instance = GetWebServiceInstance(url, namespaceName, classname, methodname, args); 26 System.Reflection.MethodInfo m = instance.GetType().GetMethod(methodname); 27 return m.Invoke(instance, args); 28 } 29 catch (Exception ex) 30 { 31 throw ex; 32 } 33 } 34 35 /// <summary> 36 /// 一个WebService实例 37 /// </summary> 38 private static object ServiceInstance = null; 39 private static object GetWebServiceInstance(string url, string namespaceName, string classname, string methodname, object[] args) 40 { 41 if (ServiceInstance != null) return ServiceInstance; 42 string @namespace = namespaceName; 43 if (namespaceName == null) 44 { 45 @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling"; 46 } 47 if ((classname == null) || (classname == "")) 48 { 49 classname = WebserviceHelper.GetWsClassName(url); 50 } 51 try 52 { 53 //获取WSDL 54 WebClient wc = new WebClient(); 55 Stream stream = wc.OpenRead(url + "?WSDL"); 56 ServiceDescription sd = ServiceDescription.Read(stream); 57 ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); 58 sdi.AddServiceDescription(sd, "", ""); 59 CodeNamespace cn = new CodeNamespace(@namespace); 60 61 //生成客户端代理类代码 62 CodeCompileUnit ccu = new CodeCompileUnit(); 63 ccu.Namespaces.Add(cn); 64 sdi.Import(cn, ccu); 65 CSharpCodeProvider csc = new CSharpCodeProvider(); 66 ICodeCompiler icc = csc.CreateCompiler(); 67 68 //设定编译参数 69 CompilerParameters cplist = new CompilerParameters(); 70 cplist.GenerateExecutable = false; 71 cplist.GenerateInMemory = true; 72 cplist.ReferencedAssemblies.Add("System.dll"); 73 cplist.ReferencedAssemblies.Add("System.XML.dll"); 74 cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); 75 cplist.ReferencedAssemblies.Add("System.Data.dll"); 76 //编译代理类 77 CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu); 78 if (true == cr.Errors.HasErrors) 79 { 80 System.Text.StringBuilder sb = new System.Text.StringBuilder(); 81 foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) 82 { 83 sb.Append(ce.ToString()); 84 sb.Append(System.Environment.NewLine); 85 } 86 throw new Exception(sb.ToString()); 87 } 88 //生成代理实例,并调用方法 89 System.Reflection.Assembly assembly = cr.CompiledAssembly; 90 Type t = assembly.GetType(@namespace + "." + classname, true, true); 91 ServiceInstance = Activator.CreateInstance(t); 92 return ServiceInstance; 93 } 94 catch (Exception ex) 95 { 96 throw ex; 97 } 98 } 99 100 /// <summary> 101 /// 获取web服务类名 102 /// </summary> 103 /// <param name="wsUrl">web服务地址</param> 104 /// <returns>web服务类名</returns> 105 private static string GetWsClassName(string wsUrl) 106 { 107 string[] parts = wsUrl.Split('/'); 108 string[] pps = parts[parts.Length - 1].Split('.'); 109 return pps[0]; 110 } 111 }
报错:
原因分析:
1.“InvokeWebService”是个重载函数,如果webserver没有申明类名,就不传类名,代码就自动获取默认的类名,如果有申明类名,就必须要传,否则就找不到类。(来源网友)
2.如何获知类名:其实只要在vs里面导入web引用输入就可以看见类名。(实验有效)
还有一种方法就是通过代码动态获得类名。