動態調用webservice,就可以不用添加web引用了,上線的話也只是需要改一下wsdl地址就可以了
C#動態webservice調用接口
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 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 } }?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 //調用並讀取解析返回結果 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.動態調用的方法:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /// <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.動態調用具體類:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 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 } }以上所述就是本文的全部內容了,希望大家能夠喜歡。