C# 动态调用WebService

C# 动态调用WebService

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

1.动态调用的方法:
C#代码 复制代码  收藏代码
  1. /// <summary>   
  2.         ///  动态webservice调用   
  3.         /// </summary>   
  4.         /// <returns>string</returns>     
  5.         public string wsTest()   
  6.         {   
  7.             string url = "http://localhost:8080/myWebserviceTest/services/myServices?wsdl";//wsdl地址   
  8.             string name = "wsTest";//javaWebService开放的接口   
  9.             WebServiceProxy wsd = new WebServiceProxy(url, name);   
  10.   
  11.             string[] str = { "测试c#调用java的webService" , "Hello WebService"};   
  12.   
  13.             string suc = (string)wsd.ExecuteQuery(name, str);   
  14.   
  15.             return suc;   
  16.         }  


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


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

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

黑色头发:http://heisetoufa.iteye.com/

你可能感兴趣的:(C# 动态调用WebService)