代码改变世界

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     }
View Code

报错:

 原因分析:

1.“InvokeWebService”是个重载函数,如果webserver没有申明类名,就不传类名,代码就自动获取默认的类名,如果有申明类名,就必须要传,否则就找不到类。(来源网友)

2.如何获知类名:其实只要在vs里面导入web引用输入就可以看见类名。(实验有效)
还有一种方法就是通过代码动态获得类名。

参考:动态调用WebService 的问题~~ 不知道为什么-CSDN社区