基於Web Service的客戶端框架搭建三:代理層(Proxy)


 

前言

  代理層的主要工作是調用Web Service,將在FCL層序列化好的Json數據字符串Post到Web Service,然后獲得Reponse,再從響應流中讀取到調用結果Json字符串,在Dispatcher反序列化成數據對象,在UI層呈現出來。

 

HttpHelper類(參考自:http://blog.csdn.net/eriloan/article/details/7000790)

  剛開始是直接在Proxy類中直接寫的Post方法,后來看到這篇帖子,將Http相關的部分封裝成了工具類HttpHelper。原帖中還包含了使用TCPSocket發送請求調用WebService的內容。

  1 namespace ProjectmsMGT_Proxy
  2 {
  3     public class HttpHelper
  4     {
  5         /// <summary>
  6         /// Http請求URL
  7         /// </summary>
  8         public string Url { set; get; }
  9 
 10         /// <summary>
 11         /// 請求參數Key(約定服務方法參數名同名)
 12         /// 在使用Post方式向服務器端發送請求的時候,請求數據中包含了參數部分,參數部分我們需要告訴WebService接口方法,實參要傳給的接口方法行參名,由RequestParaKey指定
 13         /// 當然當接口方法有多個形參時,就不建議單獨設計這樣一個屬性,直接在sendMsg中添加,此處只是為了突出RequestParaKey的重要性
 14         /// </summary>
 15         public string RequestParaKey { set; get; }
 16         
 17         /// <summary>
 18         /// 證書文件路徑
 19         /// </summary>
 20         public string CertificateFilePath { set; get; }
 21 
 22         /// <summary>
 23         /// 證書文件口令
 24         /// </summary>
 25         public string CertificateFilePwd { set; get; }
 26 
 27         /// <summary>
 28         /// 構造函數,不使用證書
 29         /// </summary>
 30         /// <param name="url"></param>
 31         /// <param name="requestParaKey"></param>
 32         public HttpHelper(string url, string requestParaKey)
 33         {
 34             this.Url = url;
 35             this.RequestParaKey = requestParaKey;
 36         }
 37 
 38         /// <summary>
 39         /// 構造函數,使用證書
 40         /// </summary>
 41         /// <param name="url"></param>
 42         /// <param name="requestParaKey"></param>
 43         /// <param name="certFilePath"></param>
 44         /// <param name="certFilePwd"></param>
 45         public HttpHelper(string url, string requestParaKey, string certFilePath, string certFilePwd)
 46         {
 47             this.Url = url;
 48             this.RequestParaKey = requestParaKey;
 49             this.CertificateFilePath = certFilePath;
 50             this.CertificateFilePwd = certFilePwd;
 51         }
 52 
 53         /// <summary>
 54         /// 使用Get方式,發送Http請求
 55         /// </summary>
 56         /// <param name="methodName">所請求的接口方法名</param>
 57         /// <param name="isLoadCert">是否加載證書</param>
 58         /// <returns>響應字符串</returns>
 59         public string CreateHttpGet(string methodName, bool isLoadCert)
 60         {
 61             HttpWebRequest request = CreateHttpRequest(methodName, @"GET", isLoadCert);
 62 
 63             return CreateHttpResponse(request);
 64         }
 65 
 66         /// <summary>
 67         /// 使用Post方式,發送Http請求
 68         /// </summary>
 69         /// <param name="methodName">所請求的接口方法名</param>
 70         /// <param name="sendMsg">請求參數(不包含RequestParaKey部分)</param>
 71         /// <param name="isLoadCert">是否加載證書</param>
 72         /// <returns>響應字符串</returns>
 73         public string CreateHttpPost(string methodName, string sendMsg, bool isLoadCert)
 74         {
 75             //創建Http請求
 76             HttpWebRequest request = CreateHttpRequest(methodName, @"POST", isLoadCert);
 77             if (null != sendMsg && !"".Equals(sendMsg))
 78             {
 79                 //添加請求參數
 80                 AddHttpRequestParams(request, sendMsg);
 81             }
 82 
 83             //獲得響應
 84             return CreateHttpResponse(request);
 85         }
 86 
 87         /// <summary>
 88         /// 將請求參數寫入請求流
 89         /// </summary>
 90         /// <param name="request"></param>
 91         /// <param name="sendMsg"></param>
 92         private void AddHttpRequestParams(HttpWebRequest request, string sendMsg)
 93         {
 94             //將請求參數進行URL編碼
 95             string paraUrlCoded = System.Web.HttpUtility.UrlEncode(RequestParaKey) + "=" +
 96                 System.Web.HttpUtility.UrlEncode(sendMsg);
 97 
 98             byte[] data = Encoding.UTF8.GetBytes(paraUrlCoded);
 99             request.ContentLength = data.Length;
100             Stream requestStream = null;
101             using (requestStream = request.GetRequestStream())
102             {
103                 //將請求參數寫入流
104                 requestStream.Write(data, 0, data.Length);
105             }
106 
107             requestStream.Close(); 
108         }
109 
110         /// <summary>
111         /// 創建HttpRequest
112         /// </summary>
113         /// <param name="methodName"></param>
114         /// <param name="requestType">POST或者GET</param>
115         /// <param name="isLoadCert"></param>
116         /// <returns>HttpWebRequest對象</returns>
117         private HttpWebRequest CreateHttpRequest(string methodName, string requestType, bool isLoadCert)
118         {
119             HttpWebRequest request = null;
120             try
121             {
122                 string requestUriString = Url + "/" + methodName;
123                 request = (HttpWebRequest)WebRequest.Create(requestUriString);
124                 if (isLoadCert)
125                 {
126                     //創建證書
127                     X509Certificate2 cert = CreateX509Certificate2();
128                     //添加證書認證
129                     request.ClientCertificates.Add(cert);
130                 }
131                 request.KeepAlive = true;
132                 request.ContentType = "application/x-www-form-urlencoded";
133                 request.Method = requestType;
134             }
135             catch (Exception)
136             {
137                 //Console.WriteLine("創建HttpRequest失敗。原因:" + e.Message);
138                 request = null;
139             }
140 
141             return request;
142         }
143 
144         /// <summary>
145         /// 創建請求響應
146         /// </summary>
147         /// <param name="request"></param>
148         /// <returns>響應字符串</returns>
149         private string CreateHttpResponse(HttpWebRequest request)
150         {
151             String str;
152             HttpWebResponse response = null;
153             Stream responseStream = null;
154             XmlTextReader responseReader = null;
155             try
156             {
157                 using (response = (HttpWebResponse)request.GetResponse())
158                 {
159                     //獲得響應流
160                     responseStream = response.GetResponseStream();
161                     responseReader = new XmlTextReader(responseStream);
162                     responseReader.MoveToContent();
163                     str = responseReader.ReadInnerXml();
164                 }
165             }
166             catch (Exception e)
167             {
168                 str = "[{\"Rescode\":\"0\",\"Resmsg\":\"通信失敗。原因:" + e.Message + "\"}]";
169             }
170             finally
171             {
172                 if (null != response)
173                 {
174                     responseReader.Close();
175                     responseStream.Close();
176                     response.Close();
177                 }
178             }
179 
180             return str; 
181         }
182 
183         /// <summary>
184         /// 創建證書
185         /// </summary>
186         /// <returns>X509Certificate2對象</returns>
187         private X509Certificate2 CreateX509Certificate2()
188         {
189             X509Certificate2 cert = null;
190             try
191             {
192                 cert = new X509Certificate2(CertificateFilePath, CertificateFilePwd);
193                 ServicePointManager.ServerCertificateValidationCallback = 
194                     new RemoteCertificateValidationCallback(ServerCertificateValidationCallback);
195             }
196             catch (Exception)
197             {
198                 //Console.WriteLine("創建X509Certificate2失敗。原因:" + e.Message);  
199                 cert = null;
200             }
201             return cert;
202         }
203 
204         /// <summary>
205         /// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
206         /// </summary>
207         /// <param name="obj">An object that contains state information for this validation</param>
208         /// <param name="cer">The certificate used to authenticate the remote party</param>
209         /// <param name="chain">The chain of certificate authorities associated with the remote certificate</param>
210         /// <param name="error">One or more errors associated with the remote certificate</param>
211         /// <returns>A Boolean value that determines whether the specified certificate is accepted for authentication</returns>
212         private bool ServerCertificateValidationCallback(object obj, X509Certificate cer, X509Chain chain, System.Net.Security.SslPolicyErrors error)
213         {
214             return true;
215         } 
216     }
217 }

  HttpHelper中把SSL證書的部分也包含進來,但是證書認證機制部分ServerCertificateValidationCallback還沒設計,各位大神可以自行發揮。

 

代理類Proxy

  有了HttpHelper之后,代理類的代碼就比較明了了。

 1 namespace ProjectmsMGT_Proxy
 2 {
 3     public class ProjectmsProxy
 4     {
 5         private readonly string Url = "http://59.68.29.106:8087/IFT_Project.asmx";//通過配置文件獲取Web Service地址
 6         private readonly string requestParaKey = "paramaters";//服務端所有接口函數統一的參數名
 7         private HttpHelper httpHelper;
 8 
 9         public ProjectmsProxy()
10         {
11             //初始化
12             Initialize();
13         }
14 
15         private void Initialize()
16         {
17             httpHelper = new HttpHelper(this.Url, this.requestParaKey);
18         }
19 
20         /// <summary>
21         /// 使用Get方式調用WebService,不帶參數
22         /// </summary>
23         /// <param name="methodName"></param>
24         /// <param name="parasJsonStr"></param>
25         /// <param name="requestType"></param>
26         /// <returns></returns>
27         public string Excute(string methodName, string parasJsonStr, string requestType)
28         {
29             return httpHelper.CreateHttpGet(methodName, false);
30         }
31 
32         /// <summary>
33         /// 默認使用Post方式調用WebService,帶參數
34         /// </summary>
35         /// <param name="methodName"></param>
36         /// <param name="parasJsonStr"></param>
37         /// <returns></returns>
38         public string Excute(string methodName, string parasJsonStr)
39         {
40             return httpHelper.CreateHttpPost(methodName, parasJsonStr, false);
41         }
42 
43         /// <summary>
44         /// 默認使用Post方式調用WebService,不帶參數
45         /// </summary>
46         /// <param name="methodName"></param>
47         /// <returns></returns>
48         public string Excute(string methodName)
49         {
50             return httpHelper.CreateHttpPost(methodName, null, false);
51         }
52     }
53 }

  Proxy中重載了Excute方法,三個參數的表示使用Get方式調用WebService(因為不建議在Get方式下傳參給Web Service),兩個參數和一個參數的Excute默認是使用Post方式帶參數和不帶參數的情況。

 

總結

  將方法名作為參數Post到Web Service可以減少很多重復代碼,不需要對服務端的每個接口函數做寫一個代理函數,這是使用Post方式比使用添加Web服務引用方式更加靈活。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM