.asmx處理程序提供的功能之消息調度
當 .asmx處理程序由 HTTP 管道調用之后,它會通過查看在 .asmx 文件中發現的 WebService 聲明來確定要檢查哪個 .NET 類。然后,它會查看傳入的 HTTP 消息中的信息,以便正確地確定要在被引用類中調用哪種方法。要調用先前示例中顯示的 Add 操作,傳入的 HTTP 消息必須具有如下所示的外觀:
- POST /math/math.asmx HTTP/1.1
- Host: localhost
- Content-Type: text/xml; charset=utf-8
- Content-Length: length
- SOAPAction: "http://tempuri.org/Add"
- < soap:Envelope
- xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
- >
- < soap:Body>
- < Add xmlns="http://tempuri.org/">
- < x>33< /x>
- < y>66< /y>
- < /Add>
- < /soap:Body>
- < /soap:Envelope>
在傳入的 HTTP 消息中,確實有兩段信息可用來確定要在該類中調用哪種方法:SOAPAction 頭或請求元素的名稱(例如,soap:Body 元素中元素的名稱)。在本例中,任何一個都指出了發送方想調用的方法的名稱。
在默認情況下,.asmx 處理程序使用 SOAPAction 頭的值來執行消息調度。因此,.asmx 處理程序查看消息中的 SOAPAction 頭,使用 .NET 反射檢查被引用類中的方法。它只考慮標記了 [WebMethod] 屬性的方法,但是它可以通過查看每種方法的 SOAPAction 值來正確地確定要調用哪種方法。由于我們沒有對類中的方法顯式指定 SOAPAction 值,因此,.asmx 處理程序假設 SOAPAction 值將由 Web 服務的命名空間及其后面的方法名稱組成。而且我們也沒有指定命名空間,因此該處理程序會將 http://tempuri.org 作為默認的命名空間。這樣,Add 方法的默認 SOAPAction 值將是 http://tempuri.org/Add。
您可以自定義 Web 服務的命名空間,方法是用 [SoapDocumentMethod] 屬性批注自己的 WebMethod,從而使用 [WebService] 屬性以及正確的 SOAPAction 值來批注自己的類,如下所示:
- using System.Web.Services;
- using System.Web.Services.Protocols;
- [WebService(Namespace="http://example.org/math")]
- public class MathService
- {
- [WebMethod]
- public double Add(double x, double y) {
- return x + y;
- }
- [WebMethod]
- [SoapDocumentMethod(Action="urn:math:subtract")]
- public double Subtract(double x, double y) {
- return x - y;
- }
- ...
- }
現在,.asmx 處理程序希望 Add 方法的 SOAPAction 值是 http://example.org/math/Add(使用默認試探法),希望 Subtract 方法的 SOAPAction 值是 urn:math:subtract(因為我們將它顯式定義為該值)。例如,下面的 HTTP 請求消息調用 Subtract 操作:
- POST /math/math.asmx HTTP/1.1
- Host: localhost
- Content-Type: text/xml; charset=utf-8
- Content-Length: length
- SOAPAction: "urn:math:subtract"
- < soap:Envelope
- xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
- >
- < soap:Body>
- < Subtract xmlns="http://example.org/math">
- < x>33< /x>
- < y>66< /y>
- < /Subtract>
- < /soap:Body>
- < /soap:Envelope>
如果 .asmx處理程序未找到與傳入的 HTTP 消息相匹配的 SOAPAction,則它只是引發一個異常(以后會詳細介紹如何處理異常)。如果您不想依賴 SOAPAction 頭來進行方法調度,則可以用 [SoapDocumentService] 屬性的 RoutingStyle 屬性來批注該類,以便指示 .asmx 處理程序使用請求元素的名稱。如果這樣做的話,可能還應該指出 WebMethod 不需要 SOAPAction 值(通過將它們的值設置為空字符串),如下所示:
- using System.Web.Services;
- using System.Web.Services.Protocols;
- [WebService(Namespace="http://example.org/math")]
- [SoapDocumentService(
- RoutingStyle=SoapServiceRoutingStyle.RequestElement)]
- public class MathService
- {
- [WebMethod]
- [SoapDocumentMethod(Action="")]
- public double Add(double x, double y) {
- return x + y;
- }
- [WebMethod]
- [SoapDocumentMethod(Action="")]
- public double Subtract(double x, double y) {
- return x - y;
- }
- ...
- }
在本例中,該處理程序甚至不查看 SOAPAction 值,而是使用請求元素的名稱。例如,對于 Add 方法,該處理程序希望請求元素的名稱是 Add(來自 http://example.org/math 命名空間),如下面的 HTTP 請求消息中所示:
- POST /math/math.asmx HTTP/1.1
- Host: localhost
- Content-Type: text/xml; charset=utf-8
- Content-Length: length
- SOAPAction: ""
- < soap:Envelope
- xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
- >
- < soap:Body>
- < Add xmlns="http://example.org/math">
- < x>33< /x>
- < y>66< /y>
- < /Add>
- < /soap:Body>
- < /soap:Envelope>
因此,當 .asmx處理程序收到傳入的 HTTP 消息時,它做的第一件重要事情就是確定如何將該消息調度到相應的 WebMethod。但是,在能夠實際調用該方法之前,它必須將傳入的 XML 映射到 .NET 對象。
【編輯推薦】