文章目錄
為了使.asmx控制代碼有可能反序列化SOAP頭,首先你需要定義一個.NET類,它代表了暗含的XML Schema類。在此例中相應的類如下:
[XmlType(Namespace="http://example.org/security")][XmlRoot(Namespace="http://example.org/security")]public class UsernameToken : SoapHeader { public string username; public string password;}然後你需要在WebMethod類中定義一個成員變數來控制一個頭類的執行個體,同樣要為WebMethods標記[SoapHeader]屬性。見如下:
using System;using System.Web.Services;using System.Web.Services.Protocols; [WebService(Namespace="urn:geometry")]public class Geometry { public UsernameToken Token; [WebMethod] [SoapHeader("Token")] public double Distance(Point orig, Point dest) { if (!Token.username.Equals(Reverse(Token.password))) throw new Exception("access denied"); return Math.Sqrt(Math.Pow(orig.x-dest.x, 2) + Math.Pow(orig.y-dest.y, 2)); }}這樣,在WebMethod中你可以訪問Token域,並提取SOAP頭提供的資訊。你也可以使用同樣的技術將頭資訊送回用戶端——你需要在[SoapHeader]屬性聲明中指定頭的方向。
.asmx控制代碼也提供了.NET異常的自動序列化。任何被.asmx控制代碼劫獲的未處理的異常都會被自動序列化為應答訊息中的SOAP Fault元素。比如,在前面的例子中,假如使用者名稱與反轉的口令不匹配,我們的代碼將會拋出一個.NET異常。.asmx控制代碼劫獲這個異常,將它序列化為下面的SOAP應答:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <soap:Fault> <faultcode>soap:Server</faultcode> <faultstring>Server was unable to process request. --> access denied</faultstring> <detail /> </soap:Fault> </soap:Body></soap:Envelope>如果你想更多的控制SOAP Fault元素,也可以通過指定所有SOAP Fault元素細節來明確拋出一個SOAP異常對象。比如:faultcode, faulstring, faultactor, detail元素。
領會WebMethods如何工作需要理解根本的序列化引擎和它的各種選項。序列化引擎的好處就是它隱藏了定製控制代碼中底層的XML API代碼。然而儘管許多開發人員認為這樣很好,一些人也認為這也是它的缺陷,因為他們想親手來處理WebMethod中未經加工的SOAP訊息。
自動產生WSDL文檔寫好並部署了一個WebMethod後,客戶需要明確知道和它成功通訊SOAP訊息應該是個什麼樣子。提供Web服務描述的標準方法是通過WSDL(和嵌入的XSD定義)。.asmx控制代碼自動的產生了人性化的可讀文檔和WSDL定義,它準確的反映了WebMethod介面。如果在你的WebMethods中應用了一些映射屬性,它們將都被反映在產生的文檔中。
假如你瀏覽這個.asmx檔案,你將看到一個人性化的可讀文檔頁面就像圖2中顯示的那樣。這個文檔頁是由DefaultWsdlHelpGenerator.aspx (在 C:"windows"Microsoft.NET"Framework"v1.0.3705"config中)產生的。開啟這個檔案你會看到它就是一個標準的ASP.NET頁面,它使用.NET reflection產生那個文檔。這個特點使文檔一直與代碼同步,可以通過簡單的修改這個檔案來定製你的產生文檔。
也可以在Web.config檔案中指定一個不同的文檔檔案來繞過基於虛擬目錄文檔產生器:
<configuration> <system.web> <webServices> <wsdlHelpGenerator href="MyDocumentation.aspx"/> </webServices> ...如果用戶端發出請求.asmx終點,且請求字串後加“?wsdl”,.asmx控制代碼將產生一個WSDL定義而不是一個人性化的可讀文檔。用戶端可以使用WSDL定義組建代理程式類,它自動的知道怎樣和Web服務通訊。
要定製WSDL產生過程,你可以寫一個SoapExtensionReflector類並在你的Web.config檔案中註冊到WebMethods架構。然後當.asmx控制代碼產生WSDL定義時,它將會調用你的反映類(reflector)使你有機會定製提供給使用者的最後定義。
同樣你也可以採用兩種技術來繞過WSDL產生過程。首先,可以在你的虛擬目錄下提供一個靜態WSDL文檔供客戶訪問,然後從Web.config檔案中除去文檔產生器(如下所示)。
<configuration> <system.web> <webServices> <protocols> <remove name="Documentation"/> </protocols> ...另外一個比較自動化的技術是使用[WebServiceBinding]屬性來指定WebMethod類實現的靜態WSDL文檔在虛擬目錄中的位置,也要用[SoapDocumentMethod]屬性為每一個實現的WebMethod指定WSDL綁定的名字。這樣做以後,自動WSDL產生過程將會匯入你的靜態WSDL檔案,產生一個新的服務描述。
手工編寫WSDL是極端困難的,因為現在沒有很多WSDL編輯器。因此自動文檔/WSDL產生是WebMethod架構中有價值的一部分。沒有它,許多開發人員的日子會很難過的。
總結ASP.NET WebMethods架構為建立WEB服務提供了高效的方法。WebMethods使得傳統的.NET方法能夠成為支援HTTP、XML、XML Schema和WSDL的Web服務作業。WebMethod(.asmx)控制代碼自動決定怎樣將到來的SOAP請求訊息指派到適當的方法,然後又將請求訊息中的XML元素序列化為相應的.NET對象。為簡化整合用戶端,.asmx控制代碼也支援可讀文檔和WSDL的產生。
和自己定製的IhttpHandlers相比,儘管WebMethods架構有點受限,它還是提供了稱為SOAP擴充架構的強大擴充模型。SOAP擴充允許你引入我們上面沒有討論到的額外功能來滿足你的具體需要。比如,微軟發布了Web Serivices Enhancements1.0,它提供了SoapExtension類,為WebMethods架構引入了幾個GXA規範的支援。