c#动态调用WEBSERVICE接口

C#动态webservice调用接口

复制代码
  1 using System;
  2 using System.Collections;
  3 using System.IO;
  4 using System.Net;
  5 using System.Text;
  6 using System.Xml;
  7 using System.Xml.Serialization;
  8 namespace Hishop.Plugins
  9 {
 10   /// <summary>
 11   /// 利用WebRequest/WebResponse进行WebService调用的类
 12   /// </summary>
 13   public class WebServiceCaller
 14   {
 15     #region Tip:使用说明
 16     //webServices 应该支持Get和Post调用,在web.config应该增加以下代码
 17     //<webServices>
 18     // <protocols>
 19     //  <add name="HttpGet"/>
 20     //  <add name="HttpPost"/>
 21     // </protocols>
 22     //</webServices>
 23   
 24     //调用示例:
 25     //Hashtable ht = new Hashtable(); //Hashtable 为webservice所需要的参数集
 26     //ht.Add("str", "test");
 27     //ht.Add("b", "true");
 28     //XmlDocument xx = WebSvcCaller.QuerySoapWebService("http://localhost:81/service.asmx", "HelloWorld", ht);
 29     //MessageBox.Show(xx.OuterXml);
 30     #endregion
 31   
 32     /// <summary>
 33     /// 需要WebService支持Post调用
 34     /// </summary>
 35     public static XmlDocument QueryPostWebService(String URL, String MethodName, Hashtable Pars)
 36     {
 37       HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);
 38       request.Method = "POST";
 39       request.ContentType = "application/x-www-form-urlencoded";
 40       SetWebRequest(request);
 41       byte[] data = EncodePars(Pars);
 42       WriteRequestData(request, data);
 43       return ReadXmlResponse(request.GetResponse());
 44     }
 45   
 46     /// <summary>
 47     /// 需要WebService支持Get调用
 48     /// </summary>
 49     public static XmlDocument QueryGetWebService(String URL, String MethodName, Hashtable Pars)
 50     {
 51       HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName + "?" + ParsToString(Pars));
 52       request.Method = "GET";
 53       request.ContentType = "application/x-www-form-urlencoded";
 54       SetWebRequest(request);
 55       return ReadXmlResponse(request.GetResponse());
 56     }
 57   
 58     /// <summary>
 59     /// 通用WebService调用(Soap),参数Pars为String类型的参数名、参数值
 60     /// </summary>
 61     public static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars)
 62     {
 63       if (_xmlNamespaces.ContainsKey(URL))
 64       {
 65         return QuerySoapWebService(URL, MethodName, Pars, _xmlNamespaces[URL].ToString());
 66       }
 67       else
 68       {
 69         return QuerySoapWebService(URL, MethodName, Pars, GetNamespace(URL));
 70       }
 71     }
 72   
 73     private static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars, string XmlNs)
 74     {
 75       _xmlNamespaces[URL] = XmlNs;//加入缓存,提高效率
 76       HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
 77       request.Method = "POST";
 78       request.ContentType = "text/xml; charset=utf-8";
 79       request.Headers.Add("SOAPAction", "\"" + XmlNs + (XmlNs.EndsWith("/") ? "" : "/") + MethodName + "\"");
 80       SetWebRequest(request);
 81       byte[] data = EncodeParsToSoap(Pars, XmlNs, MethodName);
 82       WriteRequestData(request, data);
 83       XmlDocument doc = new XmlDocument(), doc2 = new XmlDocument();
 84       doc = ReadXmlResponse(request.GetResponse());
 85   
 86       XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
 87       mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
 88       String RetXml = doc.SelectSingleNode("//soap:Body/*/*", mgr).InnerXml;
 89       doc2.LoadXml("<root>" + RetXml + "</root>");
 90       AddDelaration(doc2);
 91       return doc2;
 92     }
 93     private static string GetNamespace(String URL)
 94     {
 95       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");
 96       SetWebRequest(request);
 97       WebResponse response = request.GetResponse();
 98       StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
 99       XmlDocument doc = new XmlDocument();
100       doc.LoadXml(sr.ReadToEnd());
101       sr.Close();
102       return doc.SelectSingleNode("//@targetNamespace").Value;
103     }
104   
105     private static byte[] EncodeParsToSoap(Hashtable Pars, String XmlNs, String MethodName)
106     {
107       XmlDocument doc = new XmlDocument();
108       doc.LoadXml("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"></soap:Envelope>");
109       AddDelaration(doc);
110       //XmlElement soapBody = doc.createElement_x_x("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
111       XmlElement soapBody = doc.CreateElement("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");
112       //XmlElement soapMethod = doc.createElement_x_x(MethodName);
113       XmlElement soapMethod = doc.CreateElement(MethodName);
114       soapMethod.SetAttribute("xmlns", XmlNs);
115       foreach (string k in Pars.Keys)
116       {
117         //XmlElement soapPar = doc.createElement_x_x(k);
118         XmlElement soapPar = doc.CreateElement(k);
119         soapPar.InnerXml = ObjectToSoapXml(Pars[k]);
120         soapMethod.AppendChild(soapPar);
121       }
122       soapBody.AppendChild(soapMethod);
123       doc.DocumentElement.AppendChild(soapBody);
124       return Encoding.UTF8.GetBytes(doc.OuterXml);
125     }
126     private static string ObjectToSoapXml(object o)
127     {
128       XmlSerializer mySerializer = new XmlSerializer(o.GetType());
129       MemoryStream ms = new MemoryStream();
130       mySerializer.Serialize(ms, o);
131       XmlDocument doc = new XmlDocument();
132       doc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));
133       if (doc.DocumentElement != null)
134       {
135         return doc.DocumentElement.InnerXml;
136       }
137       else
138       {
139         return o.ToString();
140       }
141     }
142   
143     /// <summary>
144     /// 设置凭证与超时时间
145     /// </summary>
146     /// <param name="request"></param>
147     private static void SetWebRequest(HttpWebRequest request)
148     {
149       request.Credentials = CredentialCache.DefaultCredentials;
150       request.Timeout = 10000;
151     }
152   
153     private static void WriteRequestData(HttpWebRequest request, byte[] data)
154     {
155       request.ContentLength = data.Length;
156       Stream writer = request.GetRequestStream();
157       writer.Write(data, 0, data.Length);
158       writer.Close();
159     }
160   
161     private static byte[] EncodePars(Hashtable Pars)
162     {
163       return Encoding.UTF8.GetBytes(ParsToString(Pars));
164     }
165   
166     private static String ParsToString(Hashtable Pars)
167     {
168       StringBuilder sb = new StringBuilder();
169       foreach (string k in Pars.Keys)
170       {
171         if (sb.Length > 0)
172         {
173           sb.Append("&");
174         }
175         //sb.Append(HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(Pars[k].ToString()));
176       }
177       return sb.ToString();
178     }
179   
180     private static XmlDocument ReadXmlResponse(WebResponse response)
181     {
182       StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
183       String retXml = sr.ReadToEnd();
184       sr.Close();
185       XmlDocument doc = new XmlDocument();
186       doc.LoadXml(retXml);
187       return doc;
188     }
189   
190     private static void AddDelaration(XmlDocument doc)
191     {
192       XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null);
193       doc.InsertBefore(decl, doc.DocumentElement);
194     }
195   
196     private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace
197   }
198 }
复制代码

 

复制代码
 1 //调用并读取解析返回结果
 2   
 3  DataSet ds = new DataSet(); 
 4     XmlNode xmlNode1;
 5     XmlDataDocument xd = new XmlDataDocument();
 6     StringBuilder sb; 
 7     Hashtable ht = new Hashtable();
 8     ht.Add("xmlIn", "<Request><MemCode>001</MemCode></Request>");
 9     xmlNode1 = Hishop.Plugins.WebServiceCaller.QuerySoapWebService("http://xxx.xxxx.com/Service.asmx", "SinPointQuery", ht);
10     if (xmlNode1 == null)
11     {
12       return;
13     }
14     string xmlstr= HttpUtility.HtmlDecode(xmlNode1.OuterXml);
15     sb = new StringBuilder(xmlstr);
16     if (sb.ToString().Equals(""))
17     {
18       return;
19     }
20     xd.LoadXml(sb.ToString());
21     ds.ReadXml(new XmlNodeReader(xd)); 
22     //ds可以返回出结果集
复制代码

 

 

--------------------------------------------------------------------------------------------------------

 

 

示例二 :

1.动态调用的方法:

复制代码
 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.动态调用具体类:

复制代码
using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Data; 
using System.Linq; 
using System.Web; 
using System.Web.Services; 
using System.Web.Services.Protocols; 
using System.Xml.Linq; 
  
  
using System.IO; 
using System.Net; 
using System.CodeDom; 
using System.CodeDom.Compiler; 
using System.Web.Services.Description; 
using System.Xml.Serialization; 
using System.Web.Services.Discovery; 
using System.Xml.Schema; 
using System.Text; 
using System.Security.Cryptography; 
using System.Reflection; 
using System.Collections.Generic; 
using System.Xml; 
  
namespace TPSVService 
{ 
  /// <summary> 
  /// WebServiceProxy 的摘要说明 
  /// </summary> 
  [WebService(Namespace = "http://tempuri.org/")] 
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
  [ToolboxItem(false)] 
  // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 
  // [System.Web.Script.Services.ScriptService] 
  public class WebServiceProxy : System.Web.Services.WebService 
  { 
  
    #region 私有变量和属性定义 
    /// <summary>          
    /// web服务地址              
    /// </summary>               
    private string _wsdlUrl = string.Empty; 
    /// <summary>          
    /// web服务名称              
    /// </summary>               
    private string _wsdlName = string.Empty; 
    /// <summary>          
    /// 代理类命名空间              
    /// </summary>               
    private string _wsdlNamespace = "FrameWork.WebService.DynamicWebServiceCalling.{0}"; 
    /// <summary>          
    /// 代理类类型名称              
    /// </summary>               
    private Type _typeName = null; 
    /// <summary>          
    /// 程序集名称               
    /// </summary>               
    private string _assName = string.Empty; 
    /// <summary>          
    /// 代理类所在程序集路径              
    /// </summary>               
    private string _assPath = string.Empty; 
    /// <summary>          
    /// 代理类的实例              
    /// </summary>               
    private object _instance = null; 
    /// <summary>          
    /// 代理类的实例              
    /// </summary>               
    private object Instance 
    { 
      get
      { 
        if (_instance == null) 
        { 
          _instance = Activator.CreateInstance(_typeName); 
          return _instance; 
        } 
        else
          return _instance; 
      } 
    } 
    #endregion 
  
    #region 构造函数 
    public WebServiceProxy(string wsdlUrl) 
    { 
  
      this._wsdlUrl = wsdlUrl; 
      string wsdlName = WebServiceProxy.getWsclassName(wsdlUrl); 
      this._wsdlName = wsdlName; 
      this._assName = string.Format(_wsdlNamespace, wsdlName); 
      this._assPath = Path.GetTempPath() + this._assName + getMd5Sum(this._wsdlUrl) + ".dll"; 
      this.CreateServiceAssembly(); 
    } 
  
    public WebServiceProxy(string wsdlUrl, string wsdlName) 
    { 
      this._wsdlUrl = wsdlUrl; 
      this._wsdlName = wsdlName; 
      this._assName = string.Format(_wsdlNamespace, wsdlName); 
      this._assPath = Path.GetTempPath() + this._assName + getMd5Sum(this._wsdlUrl) + ".dll"; 
      this.CreateServiceAssembly(); 
    } 
    #endregion 
  
    #region 得到WSDL信息,生成本地代理类并编译为DLL,构造函数调用,类生成时加载 
    /// <summary>              
    /// 得到WSDL信息,生成本地代理类并编译为DLL              
    /// </summary>               
    private void CreateServiceAssembly() 
    { 
      if (this.checkCache()) 
      { 
        this.initTypeName(); 
        return; 
      } 
      if (string.IsNullOrEmpty(this._wsdlUrl)) 
      { 
        return; 
      } 
      try
      { 
        //使用WebClient下载WSDL信息             
        WebClient web = new WebClient(); 
        Stream stream = web.OpenRead(this._wsdlUrl); 
        ServiceDescription description = ServiceDescription.Read(stream);//创建和格式化WSDL文档 
        ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//创建客户端代理代理类 
        importer.ProtocolName = "Soap"; 
        importer.Style = ServiceDescriptionImportStyle.Client; //生成客户端代理             
        importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync; 
        importer.AddServiceDescription(description, null, null);//添加WSDL文档 
        //使用CodeDom编译客户端代理类          
        CodeNamespace nmspace = new CodeNamespace(_assName);  //为代理类添加命名空间         
        CodeCompileUnit unit = new CodeCompileUnit(); 
        unit.Namespaces.Add(nmspace); 
        this.checkForImports(this._wsdlUrl, importer); 
        ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); 
        CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); 
        CompilerParameters parameter = new CompilerParameters(); 
        parameter.ReferencedAssemblies.Add("System.dll"); 
        parameter.ReferencedAssemblies.Add("System.XML.dll"); 
        parameter.ReferencedAssemblies.Add("System.Web.Services.dll"); 
        parameter.ReferencedAssemblies.Add("System.Data.dll"); 
        parameter.GenerateExecutable = false; 
        parameter.GenerateInMemory = false; 
        parameter.IncludeDebugInformation = false; 
        CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit); 
        provider.Dispose(); 
        if (result.Errors.HasErrors) 
        { 
          string errors = string.Format(@"编译错误:{0}错误!", result.Errors.Count); 
          foreach (CompilerError error in result.Errors) 
          { 
            errors += error.ErrorText; 
          } 
          throw new Exception(errors); 
        } 
        this.copyTempAssembly(result.PathToAssembly); 
        this.initTypeName(); 
      } 
      catch (Exception e) 
      { 
        throw new Exception(e.Message); 
      } 
    } 
    #endregion 
  
    #region 执行Web服务方法 
    /// <summary>              
    /// 执行代理类指定方法,有返回值                
    /// </summary>                 
    /// <param  name="methodName">方法名称</param>              
    /// <param  name="param">参数</param>               
    /// <returns>object</returns>                 
    public object ExecuteQuery(string methodName, object[] param) 
    { 
      object rtnObj = null;  
      string[] args = new string[2]; 
      List<string> list = new List<string>(); 
      List<string> list1 = new List<string>(); 
      List<string> list2 = new List<string>(); 
      object[] obj = new object[3]; 
  
      try
      { 
        if (this._typeName == null) 
        { 
          //记录Web服务访问类名错误日志代码位置 
          throw new TypeLoadException("Web服务访问类名【" + this._wsdlName + "】不正确,请检查!"); 
        } 
        //调用方法 
        MethodInfo mi = this._typeName.GetMethod(methodName); 
        if (mi == null) 
        { 
          //记录Web服务方法名错误日志代码位置 
          throw new TypeLoadException("Web服务访问方法名【" + methodName + "】不正确,请检查!"); 
        } 
        try
        { 
          if (param == null) 
            rtnObj = mi.Invoke(Instance, null); 
          else { 
            list.Add("Hello "); 
            list.Add("WebService "); 
            list.Add(" ! "); 
  
            list1.Add("I "); 
            list1.Add("am "); 
            list1.Add("test "); 
  
            list2.Add("do "); 
            list2.Add("it "); 
            list2.Add("now "); 
  
            obj[0] = list; 
            obj[1] = list1; 
            obj[2] = list2; 
  
            rtnObj = mi.Invoke(Instance, new object[] { obj }); 
            //rtnObj = mi.Invoke(Instance, new object[] { param }); 
          } 
        } 
        catch (TypeLoadException tle) 
        { 
          //记录Web服务方法参数个数错误日志代码位置 
          throw new TypeLoadException("Web服务访问方法【" + methodName + "】参数个数不正确,请检查!", new TypeLoadException(tle.StackTrace)); 
        } 
      } 
      catch (Exception ex) 
      { 
        throw new Exception(ex.Message, new Exception(ex.StackTrace)); 
      } 
      return rtnObj; 
    } 
  
    /// <summary>              
    /// 执行代理类指定方法,无返回值                
    /// </summary>                 
    /// <param  name="methodName">方法名称</param>              
    /// <param  name="param">参数</param>               
    public void ExecuteNoQuery(string methodName, object[] param) 
    { 
      try
      { 
        if (this._typeName == null) 
        { 
          //记录Web服务访问类名错误日志代码位置 
          throw new TypeLoadException("Web服务访问类名【" + this._wsdlName + "】不正确,请检查!"); 
        } 
        //调用方法 
        MethodInfo mi = this._typeName.GetMethod(methodName); 
        if (mi == null) 
        { 
          //记录Web服务方法名错误日志代码位置 
          throw new TypeLoadException("Web服务访问方法名【" + methodName + "】不正确,请检查!"); 
        } 
        try
        { 
          if (param == null) 
            mi.Invoke(Instance, null); 
          else
            mi.Invoke(Instance, param); 
        } 
        catch (TypeLoadException tle) 
        { 
          //记录Web服务方法参数个数错误日志代码位置 
          throw new TypeLoadException("Web服务访问方法【" + methodName + "】参数个数不正确,请检查!", new TypeLoadException(tle.StackTrace)); 
        } 
      } 
      catch (Exception ex) 
      { 
        throw new Exception(ex.Message, new Exception(ex.StackTrace)); 
      } 
    } 
    #endregion 
  
    #region 私有方法 
    /// <summary>                
    /// 得到代理类类型名称                 
    /// </summary>                 
    private void initTypeName() 
    { 
      Assembly serviceAsm = Assembly.LoadFrom(this._assPath); 
      Type[] types = serviceAsm.GetTypes(); 
      string objTypeName = ""; 
      foreach (Type t in types) 
      { 
        if (t.BaseType == typeof(SoapHttpClientProtocol)) 
        { 
          objTypeName = t.Name; 
          break; 
        } 
      } 
      _typeName = serviceAsm.GetType(this._assName + "." + objTypeName); 
    } 
  
    /// <summary>            
    /// 根据web  service文档架构向代理类添加ServiceDescription和XmlSchema               
    /// </summary>                 
    /// <param  name="baseWSDLUrl">web服务地址</param>              
    /// <param  name="importer">代理类</param>               
    private void checkForImports(string baseWsdlUrl, ServiceDescriptionImporter importer) 
    { 
      DiscoveryClientProtocol dcp = new DiscoveryClientProtocol(); 
      dcp.DiscoverAny(baseWsdlUrl); 
      dcp.ResolveAll(); 
      foreach (object osd in dcp.Documents.Values) 
      { 
        if (osd is ServiceDescription) importer.AddServiceDescription((ServiceDescription)osd, null, null); ; 
        if (osd is XmlSchema) importer.Schemas.Add((XmlSchema)osd); 
      } 
    } 
  
    /// <summary>              
    /// 复制程序集到指定路径                
    /// </summary>                 
    /// <param  name="pathToAssembly">程序集路径</param>               
    private void copyTempAssembly(string pathToAssembly) 
    { 
      File.Copy(pathToAssembly, this._assPath); 
    } 
  
    private string getMd5Sum(string str) 
    { 
      Encoder enc = System.Text.Encoding.Unicode.GetEncoder(); 
      byte[] unicodeText = new byte[str.Length * 2]; 
      enc.GetBytes(str.ToCharArray(), 0, str.Length, unicodeText, 0, true); 
      MD5 md5 = new MD5CryptoServiceProvider(); 
      byte[] result = md5.ComputeHash(unicodeText); 
      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < result.Length; i++) 
      { 
        sb.Append(result[i].ToString("X2")); 
      } 
      return sb.ToString(); 
    } 
  
    /// <summary>              
    /// 是否已经存在该程序集                
    /// </summary>                 
    /// <returns>false:不存在该程序集,true:已经存在该程序集</returns>                
    private bool checkCache() 
    { 
      if (File.Exists(this._assPath)) 
      { 
        return true; 
      } 
      return false; 
    } 
  
    //私有方法,默认取url入口的文件名为类名 
    private static string getWsclassName(string wsdlUrl) 
    { 
      string[] parts = wsdlUrl.Split('/'); 
      string[] pps = parts[parts.Length - 1].Split('.'); 
      return pps[0]; 
    } 
    #endregion 
  } 
} 
复制代码
posted @ 2019-05-13 11:33  厦门哈韩  阅读(347)  评论(0编辑  收藏  举报