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