首页 > 编程 > C# > 正文

C#动态webservice调用接口

2020-01-24 01:48:53
字体:
来源:转载
供稿:网友

C#动态webservice调用接口

using System;using System.Collections;using System.IO;using System.Net;using System.Text;using System.Xml;using System.Xml.Serialization;namespace Hishop.Plugins{  /// <summary>  /// 利用WebRequest/WebResponse进行WebService调用的类  /// </summary>  public class WebServiceCaller  {    #region Tip:使用说明    //webServices 应该支持Get和Post调用,在web.config应该增加以下代码    //<webServices>    // <protocols>    //  <add name="HttpGet"/>    //  <add name="HttpPost"/>    // </protocols>    //</webServices>     //调用示例:    //Hashtable ht = new Hashtable(); //Hashtable 为webservice所需要的参数集    //ht.Add("str", "test");    //ht.Add("b", "true");    //XmlDocument xx = WebSvcCaller.QuerySoapWebService("http://localhost:81/service.asmx", "HelloWorld", ht);    //MessageBox.Show(xx.OuterXml);    #endregion     /// <summary>    /// 需要WebService支持Post调用    /// </summary>    public static XmlDocument QueryPostWebService(String URL, String MethodName, Hashtable Pars)    {      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName);      request.Method = "POST";      request.ContentType = "application/x-www-form-urlencoded";      SetWebRequest(request);      byte[] data = EncodePars(Pars);      WriteRequestData(request, data);      return ReadXmlResponse(request.GetResponse());    }     /// <summary>    /// 需要WebService支持Get调用    /// </summary>    public static XmlDocument QueryGetWebService(String URL, String MethodName, Hashtable Pars)    {      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL + "/" + MethodName + "?" + ParsToString(Pars));      request.Method = "GET";      request.ContentType = "application/x-www-form-urlencoded";      SetWebRequest(request);      return ReadXmlResponse(request.GetResponse());    }     /// <summary>    /// 通用WebService调用(Soap),参数Pars为String类型的参数名、参数值    /// </summary>    public static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars)    {      if (_xmlNamespaces.ContainsKey(URL))      {        return QuerySoapWebService(URL, MethodName, Pars, _xmlNamespaces[URL].ToString());      }      else      {        return QuerySoapWebService(URL, MethodName, Pars, GetNamespace(URL));      }    }     private static XmlDocument QuerySoapWebService(String URL, String MethodName, Hashtable Pars, string XmlNs)    {      _xmlNamespaces[URL] = XmlNs;//加入缓存,提高效率      HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);      request.Method = "POST";      request.ContentType = "text/xml; charset=utf-8";      request.Headers.Add("SOAPAction", "/"" + XmlNs + (XmlNs.EndsWith("/") ? "" : "/") + MethodName + "/"");      SetWebRequest(request);      byte[] data = EncodeParsToSoap(Pars, XmlNs, MethodName);      WriteRequestData(request, data);      XmlDocument doc = new XmlDocument(), doc2 = new XmlDocument();      doc = ReadXmlResponse(request.GetResponse());       XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);      mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");      String RetXml = doc.SelectSingleNode("//soap:Body/*/*", mgr).InnerXml;      doc2.LoadXml("<root>" + RetXml + "</root>");      AddDelaration(doc2);      return doc2;    }    private static string GetNamespace(String URL)    {      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?WSDL");      SetWebRequest(request);      WebResponse response = request.GetResponse();      StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);      XmlDocument doc = new XmlDocument();      doc.LoadXml(sr.ReadToEnd());      sr.Close();      return doc.SelectSingleNode("//@targetNamespace").Value;    }     private static byte[] EncodeParsToSoap(Hashtable Pars, String XmlNs, String MethodName)    {      XmlDocument doc = new XmlDocument();      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>");      AddDelaration(doc);      //XmlElement soapBody = doc.createElement_x_x("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");      XmlElement soapBody = doc.CreateElement("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/");      //XmlElement soapMethod = doc.createElement_x_x(MethodName);      XmlElement soapMethod = doc.CreateElement(MethodName);      soapMethod.SetAttribute("xmlns", XmlNs);      foreach (string k in Pars.Keys)      {        //XmlElement soapPar = doc.createElement_x_x(k);        XmlElement soapPar = doc.CreateElement(k);        soapPar.InnerXml = ObjectToSoapXml(Pars[k]);        soapMethod.AppendChild(soapPar);      }      soapBody.AppendChild(soapMethod);      doc.DocumentElement.AppendChild(soapBody);      return Encoding.UTF8.GetBytes(doc.OuterXml);    }    private static string ObjectToSoapXml(object o)    {      XmlSerializer mySerializer = new XmlSerializer(o.GetType());      MemoryStream ms = new MemoryStream();      mySerializer.Serialize(ms, o);      XmlDocument doc = new XmlDocument();      doc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));      if (doc.DocumentElement != null)      {        return doc.DocumentElement.InnerXml;      }      else      {        return o.ToString();      }    }     /// <summary>    /// 设置凭证与超时时间    /// </summary>    /// <param name="request"></param>    private static void SetWebRequest(HttpWebRequest request)    {      request.Credentials = CredentialCache.DefaultCredentials;      request.Timeout = 10000;    }     private static void WriteRequestData(HttpWebRequest request, byte[] data)    {      request.ContentLength = data.Length;      Stream writer = request.GetRequestStream();      writer.Write(data, 0, data.Length);      writer.Close();    }     private static byte[] EncodePars(Hashtable Pars)    {      return Encoding.UTF8.GetBytes(ParsToString(Pars));    }     private static String ParsToString(Hashtable Pars)    {      StringBuilder sb = new StringBuilder();      foreach (string k in Pars.Keys)      {        if (sb.Length > 0)        {          sb.Append("&");        }        //sb.Append(HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(Pars[k].ToString()));      }      return sb.ToString();    }     private static XmlDocument ReadXmlResponse(WebResponse response)    {      StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);      String retXml = sr.ReadToEnd();      sr.Close();      XmlDocument doc = new XmlDocument();      doc.LoadXml(retXml);      return doc;    }     private static void AddDelaration(XmlDocument doc)    {      XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null);      doc.InsertBefore(decl, doc.DocumentElement);    }     private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace  }}
//调用并读取解析返回结果  DataSet ds = new DataSet();     XmlNode xmlNode1;    XmlDataDocument xd = new XmlDataDocument();    StringBuilder sb;     Hashtable ht = new Hashtable();    ht.Add("xmlIn", "<Request><MemCode>001</MemCode></Request>");    xmlNode1 = Hishop.Plugins.WebServiceCaller.QuerySoapWebService("http://xxx.xxxx.com/Service.asmx", "SinPointQuery", ht);    if (xmlNode1 == null)    {      return;    }    string xmlstr= HttpUtility.HtmlDecode(xmlNode1.OuterXml);    sb = new StringBuilder(xmlstr);    if (sb.ToString().Equals(""))    {      return;    }    xd.LoadXml(sb.ToString());    ds.ReadXml(new XmlNodeReader(xd));     //ds可以返回出结果集

示例二:

1.动态调用的方法:

/// <summary>     /// 动态webservice调用     /// </summary>     /// <returns>string</returns>      public string wsTest()     {       string url = "http://localhost:8080/myWebserviceTest/services/myServices?wsdl";//wsdl地址       string name = "wsTest";//javaWebService开放的接口       WebServiceProxy wsd = new WebServiceProxy(url, name);        string[] str = { "测试c#调用java的webService" , "Hello WebService"};        string suc = (string)wsd.ExecuteQuery(name, str);        return suc;     } 

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

以上所述就是本文的全部内容了,希望大家能够喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表