using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Xml; using System.Xml.Serialization; namespace WebService.SDK { /// /// 利用WebRequest/WebResponse进行WebService调用的类 /// /// public class SoapWSHelper { //缓存xmlNamespace,避免重复调用GetNamespace private static Hashtable XML_NAMESPACE = new Hashtable(); /// /// 通过SOAP协议动态调用webservice /// /// webservice地址 /// 调用方法名 /// 参数表 /// 结果集xml public static XmlDocument QuerySoapWebService(String url, String methodName, Hashtable pars, int timeOut) { if (XML_NAMESPACE.ContainsKey(url)) { // 名字空间在缓存中存在时,读取缓存,然后执行调用 return QuerySoapWebService(url, methodName, pars, XML_NAMESPACE[url].ToString(), timeOut); } else { // 名字空间不存在时直接从wsdl的请求中读取名字空间,然后执行调用 return QuerySoapWebService(url, methodName, pars, GetNamespace(url), timeOut); } } /// /// 通过SOAP协议动态调用webservice /// /// webservice地址 /// 调用方法名 /// 参数表 /// 名字空间 /// 结果集 private static XmlDocument QuerySoapWebService(string url, string methodName, Hashtable pars, string xmlNs, int timeOut) { //加入缓存,提高效率 XML_NAMESPACE[url] = xmlNs; // 获取请求对象 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); // 设置请求head request.Method = "POST"; request.ContentType = "text/xml; charset=utf-8"; request.Headers.Add("SOAPAction", "\"" + xmlNs + (xmlNs.EndsWith("/") ? "" : "/") + methodName + "\""); if (timeOut > 0) { request.Timeout = timeOut * 1000; } // 设置请求身份 SetWebRequest(request); // 获取soap协议 byte[] data = EncodeParsToSoap(pars, xmlNs, methodName); // 将soap协议写入请求 WriteRequestData(request, data); XmlDocument returnDoc = new XmlDocument(); XmlDocument returnValueDoc = new XmlDocument(); // 读取服务端响应 returnDoc = ReadXmlResponse(request.GetResponse()); XmlNamespaceManager mgr = new XmlNamespaceManager(returnDoc.NameTable); mgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"); // 返回结果 string RetXml = returnDoc.SelectSingleNode("//soap:Body/*/*", mgr).InnerXml; returnValueDoc.LoadXml("" + RetXml + ""); AddDelaration(returnValueDoc); /* System.Data.DataSet ds = new System.Data.DataSet(); XmlNodeReader reader = new XmlNodeReader(returnValueDoc); ds.ReadXml(reader);*/ // return returnValueDoc.OuterXml; return returnValueDoc; } /// /// 获取wsdl中的名字空间 /// /// wsdl地址 /// 名字空间 private static string GetNamespace(string url) { // 创建wsdl请求对象,并从中读取名字空间 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?WSDL"); request.Timeout = 30 * 1000; 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; } /// /// 加入soapheader节点 /// /// soap文档 private static void InitSoapHeader(XmlDocument doc) { // 添加soapheader节点 XmlElement soapHeader = doc.CreateElement("soap", "Header", "http://schemas.xmlsoap.org/soap/envelope/"); //XmlElement soapId = doc.CreateElement("userid"); //soapId.InnerText = ID; //XmlElement soapPwd = doc.CreateElement("userpwd"); //soapPwd.InnerText = PWD; //soapHeader.AppendChild(soapId); //soapHeader.AppendChild(soapPwd); doc.ChildNodes[0].AppendChild(soapHeader); } /// /// 将以字节数组的形式返回soap协议 /// /// 参数表 /// 名字空间 /// 方法名 /// 字节数组 private static byte[] EncodeParsToSoap(Hashtable pars, string xmlNs, string methodName) { XmlDocument doc = new XmlDocument(); // 构建soap文档 doc.LoadXml( ""); // 加入soapbody节点 InitSoapHeader(doc); // 创建soapbody节点 XmlElement soapBody = doc.CreateElement("soap", "Body", "http://schemas.xmlsoap.org/soap/envelope/"); // 根据要调用的方法创建一个方法节点 XmlElement soapMethod = doc.CreateElement(methodName); soapMethod.SetAttribute("xmlns", xmlNs); // 遍历参数表中的参数键 foreach (string key in pars.Keys) { // 根据参数表中的键值对,生成一个参数节点,并加入方法节点内 XmlElement soapPar = doc.CreateElement(key); soapPar.InnerXml = ObjectToSoapXml(pars[key]); soapMethod.AppendChild(soapPar); } // soapbody节点中加入方法节点 soapBody.AppendChild(soapMethod); // soap文档中加入soapbody节点 doc.DocumentElement.AppendChild(soapBody); // 添加声明 AddDelaration(doc); // 传入的参数有DataSet类型,必须在序列化后的XML中的diffgr:diffgram/NewDataSet节点加xmlns='' 否则无法取到每行的记录。 XmlNode node = doc.DocumentElement.SelectSingleNode("//NewDataSet"); if (node != null) { XmlAttribute attr = doc.CreateAttribute("xmlns"); attr.InnerText = ""; node.Attributes.Append(attr); } // 以字节数组的形式返回soap文档 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(); } } /// /// 设置请求身份 /// /// 请求 private static void SetWebRequest(HttpWebRequest request) { request.Credentials = CredentialCache.DefaultCredentials; //request.Timeout = 10000; } /// /// 将soap协议写入请求 /// /// 请求 /// soap协议 private static void WriteRequestData(HttpWebRequest request, byte[] data) { request.ContentLength = data.Length; Stream writer = request.GetRequestStream(); writer.Write(data, 0, data.Length); writer.Close(); } /// /// 将响应对象读取为xml对象 /// /// 响应对象 /// xml对象 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; } /// /// 给xml文档添加声明 /// /// xml文档 private static void AddDelaration(XmlDocument doc) { XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", null); doc.InsertBefore(decl, doc.DocumentElement); } /// /// 调用WebService接口并返回结果 /// /// WebService接口地址 /// WebService接口名称 /// WebService接口参数 /// public static string QuerySoapWebServiceString(string url, string methodName, Hashtable pars) { XmlDocument doc = QuerySoapWebService(url, methodName, pars, 30); return doc.InnerText; } /// /// 调用WebService接口并返回结果 /// /// WebService接口地址 /// WebService接口名称 /// WebService接口参数 /// 连接超时时间,单位:秒 /// public static string QuerySoapWebServiceString(string url, string methodName, Hashtable pars, int timeOut) { XmlDocument doc = QuerySoapWebService(url, methodName, pars, timeOut); return doc.InnerText; } } }