天天看點

用ASP.NET開發Web服務的五則技巧

文章來源:仙人掌工作室

一、禁用HTTP POST/GET協定 

  除非另外指定,否則,.NET将試圖把Web服務綁定到三種協定:HTTP/POST、HTTP/GET和SOAP。之是以說“試圖”,是因為依賴于服務的參數和傳回類型,HTTP/GET協定可能不可用。.NET生成的WSDL檔案将自動包含綁定這三種協定的指令,客戶程式可以自由選擇使用哪種協定與服務通信。 

  隻要在Web.config檔案中加入下列内容,就可以友善地删除對HTTP/POST和HTTP/GET協定的綁定:

  <webservices>

   <protocols>

   <remove name="HttpPost" />

   <remove name="HttpGet" />

   </protocols>

  </webservices> 

  為什麼要避免通過HTTP/POST和HTTP/GET協定引出Web服務呢?主要的兩個原因是安全和互操作性。HTTP/GET的安全性不如SOAP,而且由于HTTP/GET常見于Web連結,懷有惡意的人可能利用它實施欺騙,使别人在不知不覺中用自己的安全辨別調用Web服務,卻還以為自己在點選Web連結。 

  就互操作性而言,SOAP是廣泛應用的Web服務通信标準,而HTTP/GET和HTTP/POST不是。是以,對于.NET生成的WSDL文檔中預設包含的HTTP/GET和HTTP/POST綁定,許多自動生成代理伺服器的工具不會了解。是以,如果你的Web服務不是非綁定到HTTP/GET和HTTP/POST協定不可,最好取消這兩種綁定。 

  二、用tcpTrace檢視SOAP請求/應答消息 

  對于開發Web服務應用的人來說,調試可能是件異乎尋常的難事,因為無論是.NET SDK還是VS.NET,都沒有提供工具來檢視用戶端和伺服器之間的SOAP消息。 

  如果.NET和非.NET的用戶端、伺服器端的互動過程出現了問題,要想找出問題的根源,擁有檢視SOAP消息的能力就尤為重要,因為這類問題往往與SOAP消息的格式有關(例如,“消息中包含了SOAPAction 嗎?”)。 

  tcpTrace(www.pocketsoap.com/tcptrace)是一個檢視這類消息交換過程的優秀工具,它通過設定一個用戶端和伺服器端之間的隧道工作。啟動tcpTrace時,它會要求輸入目标URL和端口号,以及tcpTrace監聽的本地端口号。這樣,你就可以通過設定代理stub的Url屬性,把stub指向這個本地端口(例如,localhost:8080)。tcpTrace能夠記錄所有的請求和應答HTTP消息。 

  tcpTrace的一個局限是,它在消息流程中所處的位置決定了它不能用來檢視通過SSL發送的消息。如果你要檢視通過SSL發送的SOAP消息,隻能編寫一個定制的ISAPI過濾器。 

  三、簡化接口設計 

  在衆多有關n-層應用設計的論述中,簡化接口設計這一設計要訣可以說是随處可見。但是,對于Web服務這樣的分布式計算環境,簡化接口設計的重要性更加突出。 

  在設計分布式應用時,出于性能和可伸縮性的考慮,應當保證用戶端和伺服器端之間的調用盡可能地少。減少網絡調用不僅有利于減少通信開銷(如果隻用一個SOAP消息可以達到目标,就絕對不要發三個消息),降低網絡流量,而且提高了應用的性能。顯然,這一切都是開發者夢寐以求的目标。那麼簡化的接口到底有何特征呢? 

  首先來看一個複雜接口的例子:

  namespace ChattyService {

   public class ChattyService : WebService {

   private string username;

   private string password;

   public string Username {

   [WebMethod]

   set {

   username = Username;

   } }

   public string Password {

   password = Password;

   public bool Logon() {

   // 驗證身份

   return true;

   }

  } 

  在這個例子中,username和password是兩個屬性,調用logon()方法之前首先必須設定這兩個屬性。有一個問題光看這段代碼不太容易注意到,這就是username和password都作為Web方法引出。這就是說,每次對屬性的get/set操作都會導緻一個對服務的調用。 

  按照簡化接口設計的要求,改進後的代碼如下:

   public bool Logon(string Username, string Password) {

  現在,username和password成了logon()方法的參數。修改之後的代碼的優點在于,它把登入操作對伺服器的三次調用降低到了一次。另一方面,如果參數的個數太多,這個方法可能看起來很不像樣。這時,可能要把方法的參數整理成幾個複雜類型,例如,把username和password兩個參數封裝到一個credential(證書)對象裡面。 

  四、在Web.Config中儲存應用私有的資料 

  用ASP.NET開發的Web服務能夠發揮出.aspx應用的所有特長,包括用web.config檔案儲存應用私有資料的能力(例如,資料庫連接配接字元串、檔案路徑等)。用Web.config而不是global.asax檔案的好處在于修改配置之後不必重新構造應用。 

  五、避免使用ASP.NET會話狀态 

  .NET實作的會話狀态管理功能解決了它的前輩ASP 3.0存在的許多問題,例如請求串行化等,但仍存在一些局限。應當認識到,.NET的會話狀态管理功能不是專門為Web服務環境中的會話狀态而設計,而是為了在範圍更廣泛的ASP.NET應用中管理會話狀态而設計,它依賴于HTTP Cookie(有一種通過改寫URL實作的不需要Cookie的模式,但不适用于Web服務)。 

  Cookie是HTTP獨有的。在Web上,所有的浏覽器都支援HTTP,是以Cookie非常适合在Web應用中使用。但是,在Web服務中應用Cookie卻把服務限定到了HTTP協定上。另一方面,SOAP協定的運作是獨立于傳輸協定的,是以如果把Web服務應用限制到HTTP協定上,應用的靈活性也受到了限制,一旦要通過非HTTP的傳輸協定(例如SMTP)提供服務,事情會變得很麻煩。