码迷,mamicode.com
首页 > Web开发 > 详细

动态调用webservice

时间:2015-07-15 18:41:59      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

动态调用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, null, null);//添加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, null, null); ;  
    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. }  

动态调用webservice

标签:

原文地址:http://www.cnblogs.com/mr-lee1976/p/4648918.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!