標籤:des style blog http color io os 使用 ar
一、引言
在前面文章中分別介紹了MSMQ和.NET Remoting技術,今天繼續分享.NET 平台下另一種分布式技術——Web Services
二、Web Services 詳細介紹2.1 Web Services 概述
Web Services是支援用戶端與伺服器通過網路互操作的一種軟體系統,是一組可以通過網路調用的應用程式API。在Web Services中主要到SOAP/UDDI/WSDL這三個核心概念,下面分別介紹下這三個概念的定義。
- SOAP:SOAP(Simple Object Access Protocol,簡易物件存取通訊協定 (SOAP))是在分散或分布式的環境中交換資訊的簡單協議,是一種基於XML的協議,需要綁定一個網路傳輸協議來完成資訊的傳輸,這個協議通常是Http或Https,但也可以使其他協議。
它包括四個部分:
SOAP封裝:它定義了一個架構,描述訊息中的內容是描述,是誰發送的,誰又應當接收並處理;
SOAP編碼規則:定義了一種序列化的機制,用於表示應用程式需要使用的資料類型的執行個體;
SOAP RPC:表示一種協定,用於表示遠端程序呼叫和應答;
SOAP綁定:它定義了SOAP使用哪種協議來進行交換資訊。使用Http/TCP/UDP都可以。與WCF中的綁定概念一致。
換句話說,SOAP協議只是用來封裝訊息用的,封裝後的訊息你可以通過各種已有的協議來傳輸,如Http、Https、Tcp、UDP、SMTP等,甚至你還可以自訂協議。然而Web Service是採用基於Http協議來傳輸資料的。關於使用Https協議來訪問Web Services的方法可以參考這個文章:如何利用 SSL 調用 Web 服務。
- UDDI:是統一描述、發現和整合(Universal Description, Discovery, and Integration)的縮寫,它是一個基於XML的跨平台的描述規範,可以使世界範圍內的企業在互連網上發布自己所提供的服務供其他客戶查詢使用。
- WSDL:是Web服務描述語言(Web Services Description Language),是為描述Web服務發布的XML格式。用於描述伺服器連接埠訪問方式和使用協議的細節,通常用來輔助生產伺服器和用戶端代碼及配置資訊。
2.2 Web Services 實現過程
調用Web Services的實現過程與進行常規方法調用過程類似。不同的在於,前者方法並不位於用戶端應用程式中,而是通過指定傳輸協議產生請求訊息。因為Web Services可能位於不同的電腦上,因此必須將Web Services處理請求所需的資訊通過網路傳遞給含有Web Services的伺服器,Web Services在處理資訊後,會通過網路將結果發送回用戶端應用程式。顯示了用戶端與Web Services之間的通訊過程:
下面介紹下調用Web Services時事件發生順序:
- 在用戶端上,建立了一個Web Services代理類的執行個體。該對象駐留在用戶端機器上。
- 用戶端調用代理類上的方法
- 用戶端機器將Web Services方法的參數序列化為SOAP訊息,然後通過傳送協議發送給Web Services。
- Web Services底層結構接收SOAP訊息並進行還原序列化。它會建立Web Services的類的執行個體,同時調用對應的Web Services方法。
- Web Services方法執行,並返回結果。
- Web Services底層結構會將返回結果序列化為SOAP訊息,然後通過網路發送回用戶端。
- 用戶端將接收SOAP訊息,然後將XML反序列為傳回值或任何輸出參數,並將它們傳遞給代理類的執行個體。
- 用戶端接收傳回值和所有輸出參數。
2.3 Web Services 優缺點
經過上面詳細的介紹後,Web Services很明顯具有以下優點:
- 跨平台:Web Services完全基於XML(可延伸標記語言 (XML))、XSD(XMLSchema)等與平台無關的行業標準。
- 自描述:Web Service使用WSDL進行自我描述,包括服務的方法、參數、類型和傳回值等相關資訊。
- 跨防火牆:Web Service使用http協議進行通訊,可以穿越防火牆。
Web Services也具有以下缺點:
- 效率低下,不適合做單應用系統的開發。
- 安全問題:Web Services沒有自身的安全機制,必須藉助Http協議或IIS等宿主程式實現資訊安全加密。
三、使用Web Services來開發分布式應用程式
使用Web Services來開發分布式應用較MSMQ和.NET Remoting來說相對簡單很多,今天的樣本程式分三步走:
- 建立一個實現使用者資訊驗證的項目WebServiceUserValidation。具體的實現代碼如下所示:
1 namespace WebServiceUserValidation 2 { 3 public class UserValidation 4 { 5 // 判斷使用者名稱和密碼是否有效 6 public static bool IsUserLegal(string name, string psw) 7 { 8 // 使用者可以訪問資料庫進行使用者和密碼驗證 9 // 這裡僅僅作為示範10 string password = "LearningHard";11 if (string.Equals(password, psw))12 {13 return true;14 }15 else 16 {17 return false;18 }19 }20 21 // 判斷使用者的憑證是否有效22 public static bool IsUserLegal(string token)23 {24 // 使用者可以訪問資料庫進行使用者憑證驗證25 // 這裡只做示範26 string password = "LearningHard";27 if (string.Equals(password, token))28 {29 return true;30 }31 else32 {33 return false;34 }35 }36 }37 }
2. 建立Web Services服務類,需要建立一個繼承自SoapHeader,來接收SOAP 頭裡的訊息,並添加WebServiceUserValidation程式集。通過添加Asp.net 空Web應用程式來建立Web Services服務工程,再右鍵建立的Web 應用程式工程添加一個Web 服務檔案來建立Web 服務。具體的實現代碼如下所示:
// 使用者自訂的SoapHeader類必須繼承於SoapHeader public class MySoapHeader : SoapHeader { // 儲存使用者憑證 public string Token { get; set; } } /// <summary> /// LearningHardWebService 的摘要說明 /// </summary> [WebService(Namespace = "http://www.cnblogs.com/zhili/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允許使用 ASP.NET AJAX 從指令碼中調用此 Web 服務,請取消注釋以下行。 // [System.Web.Script.Services.ScriptService] public class LearningHardWebService : System.Web.Services.WebService { // 儲存使用者憑證的Soap Header資訊 // 必須保證是public和欄位名必須與SoapHeader("memberName")中memberName一樣 // 否則會出現“頭屬性/欄位 LearningHardWebService.authenticationToken 缺失或者不是公用的。”的異常 public MySoapHeader authenticationToken; private const string TOKEN = "LearningHard"; // 儲存伺服器端憑證 // 定義SoapHeader傳遞的方向 //SoapHeaderDirection.In;只發送SoapHeader到服務端,該值是預設值 //SoapHeaderDirection.Out;只發送SoapHeader到用戶端 //SoapHeaderDirection.InOut;發送SoapHeader到服務端和用戶端 //SoapHeaderDirection.Fault;服務端方法異常的話,會發送異常資訊到用戶端 [SoapHeader("authenticationToken", Direction = SoapHeaderDirection.InOut)] [WebMethod(EnableSession = false)] public string HelloLearningHard() { if (authenticationToken != null && UserValidation.IsUserLegal(authenticationToken.Token)) { return "LearningHard 你好,調用服務方法成功!"; } else { throw new SoapException("身分識別驗證失敗", SoapException.ServerFaultCode); } } }
在上面代碼中需要注意的是,Web Servies中的Web方法需要拋出SoapExcetion異常才能被用戶端捕獲到,如果在Debug模式下調試啟動並執行話,還需要在異常設定裡把這個異常勾選掉,即編譯器不對該異常進行捕獲。
3. 建立控制台用戶端,通過加入服務參考的方式來添加Web Services,添加成功後,會在用戶端程式中建立一個代理類,用戶端可以通過該代理類來調用Web Services的方法,具體的實現代碼如下所示:
1 namespace WebServiceClient 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 // 執行個體化一個Soap協議的頭 8 MySoapHeader mySoapHeader = new MySoapHeader() { Token = "LearningHard"}; 9 string sResult = string.Empty;10 LearningHardWebServiceSoapClient learningHardWebSer = null;11 try12 {13 // 執行個體化Web服務的用戶端代理類14 learningHardWebSer = new LearningHardWebServiceSoapClient();15 // 調用Web服務上的方法16 sResult= learningHardWebSer.HelloLearningHard(ref mySoapHeader);17 // 輸出結果18 Console.WriteLine(sResult);19 }20 catch21 {22 Console.WriteLine("調用Web服務失敗!");23 }24 finally25 {26 // 釋放託管資源27 if (learningHardWebSer != null)28 {29 learningHardWebSer.Close();30 }31 }32 33 Console.WriteLine("請按任意鍵結束...");34 Console.ReadLine();35 }36 }37 }
關於Web Services異常捕獲的更多資訊可以參考MSDN:在 XML Web services 中處理和引發異常。然而在這個MSDN上的範例程式碼好像運行不成功,後面發現,該文章中的用戶端對異常的處理只處理了SoapException 異常,而此時用戶端觸發的異常時FaultException異常,所以異常處理代碼應像下面代碼一樣處理,當然也可以直接只處理Exception異常,我上面代碼就只處理這個大範圍的異常。
catch (SoapException ex) { // Do sth with SoapException } catch (Exception ex) { // Do sth with Exception }
經過上面的步驟,我們就已經完成了所有的開發工作,下面運行來測試下該程式的運行效果。把WebServiceClient作為啟動項目,直接按F5或Ctrl+F5來運行用戶端程式,你將看到如下所示的結果:
註:像一般分布式應用程式,都應用先運行伺服器端,再運行用戶端來訪問服務方法。而這裡我們運行卻直接運行用戶端就可以訪問Web Services中的Web方法了。這是因為在運行Web Services用戶端程式之前,會先把Web Services部署到IIS Express 中,你將會看到工作列右下角有,右鍵該表徵圖就可以看到啟動並執行Web Services。
四、總結
到這裡,Web Services技術的分享就結束,從下一篇文章開始,將正式進入WCF的世界。而Web Services的內容和WCF內容一樣也有很多,只是微軟官方推薦採用WCF來建立Web服務程式,如果你想更多地瞭解Web Services的內容,可以參考MSDN:使用 ASP.NET 建立的 XML Web Services 以及 XML Web Services 用戶端
本文所有範例程式碼下載:WebServiceSample
跟我一起學WCF(3)——利用Web Services開發分布式應用