C#动态webservice调用接口

作者:hebedich 时间:2023-10-18 07:22:00 

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

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

标签:C#,webservice调用接口
0
投稿

猜你喜欢

  • 学习Java之如何正确地跳出循环结构

    2021-10-21 11:21:53
  • Java map 优雅的元素遍历方式说明

    2022-11-12 16:57:28
  • Java日常练习题,每天进步一点点(58)

    2021-06-26 01:13:02
  • 解决BeanUtils.copyProperties无法成功封装的问题

    2023-11-23 14:59:23
  • Android基于HttpUrlConnection类的文件下载实例代码

    2022-08-28 02:18:49
  • Android中通过Notification&NotificationManager实现消息通知

    2023-01-01 16:57:05
  • Java读取properties文件之中文乱码问题及解决

    2021-07-19 06:43:06
  • JAVA中常见异常类

    2021-11-09 09:47:20
  • Java检查非空的三种方法总结

    2023-10-03 19:58:16
  • C#开发微信门户及应用(4) 关注用户列表及详细信息管理

    2023-06-05 07:40:43
  • mybatis的大于小于号转义符号一览

    2023-05-31 07:23:03
  • JAVA如何按字节截取字符串

    2023-11-25 13:31:41
  • Android移动应用开发指南之六种布局详解

    2022-09-10 06:23:44
  • 详解Android 进程

    2023-04-26 07:37:55
  • ThreadLocal数据存储结构原理解析

    2023-04-27 19:54:55
  • Android实现手指触控图片缩放功能

    2021-06-07 17:08:00
  • Android Service中使用Toast无法正常显示问题的解决方法

    2022-01-23 08:38:12
  • Android自定义View仿QQ运动步数效果

    2021-06-25 00:11:37
  • Spring Boot2.x集成JPA快速开发的示例代码

    2022-11-21 04:55:41
  • Java中的set集合是什么意思

    2023-02-02 15:40:31
  • asp之家 软件编程 m.aspxhome.com