http動態調用webserive

   前言

   傳統方式調用WebService是直接引用服務,生成客戶端代理類類,這種方式將ws進行了再次封裝,並以代理的方式進行調用,這種方式的優勢是簡單,方便。ide

   可是此種方式不足的地方是,當對方ws接口變動時,這邊引用的服務同時也須要編譯並部署,或者我調用方這邊想動態指定不一樣服務地址時,此方式就不太適應這種場景了。性能

    有一種方式是動態調用ws的方式。就是經過ws的服務描述獲取生成客戶端的代理並動態編譯,經過反射生成實例對象,並完成ws的調用。大體代碼以下ui

 1 /// <summary> 
 2         /// 動態調用WebService 
 3         /// </summary> 
 4         /// <param name="url">WebService地址</param> 
 5         /// <param name="classname">類名</param> 
 6         /// <param name="methodname">方法名(模塊名)</param> 
 7         /// <param name="args">參數列表</param> 
 8         /// <returns>object</returns> 
 9         public static object InvokeWebService(string url, string classname, string methodname, object[] args)
10         {
11             string @namespace = "ServiceBase.WebService.DynamicWebLoad";
12             if (classname == null || classname == "")
13             {
14                 classname = WebServiceHelper.GetClassName(url);
15             }
16             //獲取服務描述語言(WSDL) 
17             WebClient wc = new WebClient();
18             Stream stream = wc.OpenRead(url + "?WSDL");
19             ServiceDescription sd = ServiceDescription.Read(stream);
20             ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
21             sdi.AddServiceDescription(sd, "", "");
22             CodeNamespace cn = new CodeNamespace(@namespace);
23             //生成客戶端代理類代碼 
24             CodeCompileUnit ccu = new CodeCompileUnit();
25             ccu.Namespaces.Add(cn);
26             sdi.Import(cn, ccu);
27             CSharpCodeProvider csc = new CSharpCodeProvider();
28             ICodeCompiler icc = csc.CreateCompiler();
29             //設定編譯器的參數 
30             CompilerParameters cplist = new CompilerParameters();
31             cplist.GenerateExecutable = false;
32             cplist.GenerateInMemory = true;
33             cplist.ReferencedAssemblies.Add("System.dll");
34             cplist.ReferencedAssemblies.Add("System.XML.dll");
35             cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
36             cplist.ReferencedAssemblies.Add("System.Data.dll");
37             //編譯代理類 
38             CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
39             if (true == cr.Errors.HasErrors)
40             {
41                 System.Text.StringBuilder sb = new StringBuilder();
42                 foreach (CompilerError ce in cr.Errors)
43                 {
44                     sb.Append(ce.ToString());
45                     sb.Append(System.Environment.NewLine);
46                 }
47                 throw new Exception(sb.ToString());
48             }
49             //生成代理實例,並調用方法 
50             System.Reflection.Assembly assembly = cr.CompiledAssembly;
51             Type t = assembly.GetType(@namespace + "." + classname, true, true);
52             object obj = Activator.CreateInstance(t);
53             System.Reflection.MethodInfo mi = t.GetMethod(methodname);
54             return mi.Invoke(obj, args);
55         }
56 
57         private static string GetClassName(string url)
58         {
59             string[] parts = url.Split('/');
60             string[] pps = parts[parts.Length - 1].Split('.');
61             return pps[0];
62         }
View Code

   可是這種方式,最明顯的方式就是性能較差,每次都要從新生成反射調用,因此通常狀況不用它。url

     那還有別的方法嗎?spa

     那我就來講說今天在工做中用到的方法。代理

    soap請求

    首先須要知道傳統的調用方式的通行協議是關鍵,ws底層也是走的http方式,只是加了多加了soap協議在裏面,那怎麼拿到它的交互協議呢,有一個神器叫fiddler,它能夠監測http請求和響應信息。有了它,就有了協議了,剩下就是拼裝協議了。code

    仔細觀察協議後 發現它的交互結構以下xml

POST /WebServiceTest/Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
 
<?xml version="1.0" encoding="utf-8"?>
<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:Body>
    <HelloWorld xmlns="http://tempuri.org/">
      <StudentName>string</StudentName>
      <PassWord>string</PassWord>
    </HelloWorld>
  </soap:Body>
</soap:Envelope>
SOAPAction這個就是表示請求的具體方法,在請求流中,在寫入上面的基於xml的soap協議,接下來就能夠發起請求了,順利的話就能拿到響應了。 作事有根有據,仔細並專一,不經意間,就能成功不遠了。
相關文章
相關標籤/搜索