using System;
using System.Web;
using System.Xml;
using System.Collections;
using System.Net;
using System.Text;
using System.IO;
using System.Xml.Serialization;
namespace XTask.Common.Net
{
??? /// <summary>
??? ///? 利用WebRequest/WebResponse进行WebService调用的类
??? /// </summary>
??? public class WebSvcCaller
??? {
??????? //试试配置文件中加以下内容
??????? //<webServices>
??????? //? <protocols>
??????? //??? <add name="HttpGet"/>
??????? //??? <add name="HttpPost"/>
??????? //? </protocols>
??????? //</webServices>
??????? private static Hashtable _xmlNamespaces = new Hashtable();//缓存xmlNamespace,避免重复调用GetNamespace
??????? /// <summary>
??????? /// 调用webService
??????? /// </summary>
??????? /// <param name="URL">格式如:http://localhost/emailws/emailService.asmx/HelloWorld</param>
??????? public static void QuerySoapWebServiceNoReturn(String URL)
??????? {
??????????? string MethodName = URL.Substring(URL.LastIndexOf("/")+1);
??????????? string realUrl = URL.Substring(0,URL.LastIndexOf("/"));
??????????? if (_xmlNamespaces.ContainsKey(URL))
??????????? {
??????????????? QuerySoapWebService(realUrl,MethodName,null,_xmlNamespaces[realUrl].ToString());
??????????? }
??????????? else
??????????? {
??????????????? QuerySoapWebService(realUrl,GetNamespace(realUrl));
??????????? }
??????? }
??????? /// <summary>
??????? /// 有返回值的方法。
??????? /// </summary>
??????? /// <param name="URL"></param>
??????? /// <param name="MethodName"></param>
??????? /// <param name="Pars"></param>
??????? /// <param name="XmlNs"></param>
??????? /// <returns></returns>
??????? private static void 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);
??????????? request.GetResponse();
??????? }
??????? /// <summary>
??????? /// 获取命名空间
??????? /// </summary>
??????? /// <param name="URL"></param>
??????? /// <returns></returns>
??????? 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;
??????? }
??????? /// <summary>
??????? /// 转换成soap包
??????? /// </summary>
??????? /// <param name="Pars">参数</param>
??????? /// <param name="XmlNs">命名空间</param>
??????? /// <param name="MethodName">方法名</param>
??????? /// <returns>返回值</returns>
??????? 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("soap","Body","http://schemas.xmlsoap.org/soap/envelope/");
??????????? XmlElement soapMethod = doc.CreateElement(MethodName);
??????????? soapMethod.SetAttribute("xmlns",XmlNs);
??????????? if (Pars != null && Pars.Count > 0)
??????????? {
??????????????? foreach (string k in Pars.Keys)
??????????????? {
??????????????????? 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);
??????? }
??????? /// <summary>
??????? /// 转换object成xml
??????? /// </summary>
??????? /// <param name="o"></param>
??????? /// <returns></returns>
??????? 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;
??????? }
??????? /// <summary>
??????? /// 往网络流写数据
??????? /// </summary>
??????? /// <param name="request"></param>
??????? /// <param name="data"></param>
??????? private static void WriteRequestData(HttpWebRequest request,byte[] data)
??????? {
??????????? request.ContentLength = data.Length;
??????????? Stream writer = request.GetRequestStream();
??????????? writer.Write(data,data.Length);
??????????? writer.Close();
??????? }
??????? /// <summary>
??????? /// xml添加head
??????? /// </summary>
??????? /// <param name="doc"></param>
??????? private static void AddDelaration(XmlDocument doc)
??????? {
??????????? XmlDeclaration decl = doc.CreateXmlDeclaration("1.0","utf-8",null);
??????????? doc.InsertBefore(decl,doc.DocumentElement);
??????? }
??? } }