Share via


使用 SOAP 擴充功能修改 SOAP 訊息

本主題專門說明舊有技術。 應該使用下列建立 XML Web Service 及 XML Web Service 用戶端: Windows Communication Foundation.

SOAP 擴充功能可讓開發人員修改 Web 服務或 Web 服務用戶端所接收和傳送的 SOAP 訊息,來加強 Web 服務的功能。例如,您可以用現有 Web 服務來實作加密或壓縮演算法。

若要了解 SOAP 擴充功能的運作方式,首先要了解 Web 服務的存留期。如需詳細資訊,請參閱 XML Web Service 存留期分析

下圖中,會概述呼叫從用戶端至 Web 服務的主要階段。

XML Web Service 存留期

您可以看到,在 Web 服務電腦和 Web 服務用戶端電腦上的階段期間,.NET Framework 會序列化及還原序列化 XML。SOAP 擴充功能可以插入基礎結構中,以便在這些序列化和還原序列化階段前後檢查或修改 SOAP 訊息。例如,在 .NET Framework 序列化用戶端的引數之後,加密 SOAP 擴充功能可以加密 SOAP 訊息的 XML 部分,然後在 .NET Framework 還原序列化 SOAP 訊息之前,解密 Web 伺服器上的 SOAP 訊息。這些階段 (SOAP 擴充功能可以檢查或修改 SOAP 訊息) 是定義在 SoapMessageStage 列舉型別中。在這種情況下,SOAP 擴充功能是在 AfterSerialize 階段中進行加密,而在 BeforeDeserialize 階段中進行解密。

一般而言,當 SOAP 擴充功能修改 SOAP 訊息內容時,必須在用戶端和伺服器上進行修改。也就是說,如果 SOAP 擴充功能在用戶端上執行加密 SOAP 訊息,則對應的 SOAP 擴充功能必須在伺服器上解密 SOAP 訊息。如果 SOAP 訊息未解密,則 ASP.NET 基礎結構便無法將 SOAP 訊息還原序列化為物件。

不修改 SOAP 訊息的 SOAP 擴充功能 (例如只記錄 SOAP 訊息的 SOAP 擴充功能),當然可以只在用戶端上或伺服器上執行。在這種情況下,收件者收到的 SOAP 訊息就像未執行 SOAP 擴充功能一樣,而且 ASP.NET 基礎結構也可以還原序列化 SOAP 訊息。此外,如果 SOAP 擴充功能未修改 SOAP 以致無法還原序列化,SOAP 擴充功能也不需要在用戶端和伺服器上執行。

擴充 SOAPExtension 類別

若要實作 SOAP 擴充功能,請從 SoapExtension 類別衍生類別。SOAPExtension 類別中有三個必須實作的方法:

逐步主題<逐步解說:使用 SOAP 擴充功能更改 SOAP 訊息>中,會說明如何實作這些方法。

Stream 物件傳遞至 ChainStream 方法,然後此方法會傳回 Stream 物件。當 SOAP 擴充功能在每個 SoapMessageStage 期間執行並修改 SOAP 訊息時,SOAP 擴充功能應讀取傳入至 ChainStreamStream 並將其寫入至 ChainStream 傳回的 Stream。因此,在 ChainStream 方法中,一定要將這兩個 Stream 參考指派至成員變數。

衍生自 SoapExtension 的類別會使用 GetInitializerInitialize 方法,根據套用的 Web 服務或 Web 服務方法,來初始化內部資料。例如,記錄 Web 服務方法所接收和傳送 SOAP 訊息的 SOAP 擴充功能,可以初始化儲存記錄資訊的檔案名稱 (根據用來執行 SOAP 擴充功能的 Web 服務或 Web 服務方法的名稱)。

Web 服務基礎結構何時呼叫 GetInitializer 方法,以及哪些參數傳遞至方法,取決於 SOAP 擴充方法的設定方式,如下:

  • 如果 SOAP 擴充功能是使用屬性加以設定,第一次存取 Web 服務 method 時,Web 服務基礎結構會呼叫 GetInitializer

  • 如果在組態檔中設定 SOAP 擴充功能,只有第一次存取整個 Web 服務時,Web 服務基礎結構才會呼叫 GetInitializer

Web 服務基礎結構會快取 GetInitializer 方法傳回的物件。然後,每次以該 Web 服務或 Web 服務方法執行 SOAP 擴充功能時,基礎結構就會將初始設定式物件傳遞至 Initialize 方法。

標準 SOAP 處理以外的實際擴充處理是由 ProcessMessage 方法執行。每次 Web 服務基礎結構呼叫 ProcessMessage 時,它會傳遞衍生自 SoapMessage 的類別執行個體 (當做引數),其中包含該特定階段中 SOAP 訊息的相關資訊。如果 SOAP 擴充功能是以 Web 服務執行,則會傳入 SoapServerMessage 物件。如果 SOAP 擴充功能是以 Web 服務用戶端執行,則會傳入 SoapClientMessage 物件。

SOAP 擴充功能和例外狀況

SOAP 擴充功能本身絕不可擲回例外狀況。但是,它們可以在已傳入 ProcessMessage 方法的 SoapMessage 物件上的 Exception 屬性,加入例外狀況資訊。

它們也可以做為應用程式範圍的例外處理常式,使用相同功能來攔截安裝 SOAP 擴充功能的應用程式中的所有例外狀況,並且執行一些行為,包括修改所傳回的 SOAP 錯誤。

叫用 SOAP 擴充方法的順序

您已經檢視 SOAP 擴充功能覆寫的方法,現在將檢視在整個 Web 服務方法的引動過程中,Web 服務基礎結構何時叫用 SOAP 擴充方法。下列步驟假設 SOAP 擴充功能是在用戶端和伺服器上執行。如果 SOAP 擴充功能不是在用戶端和伺服器上執行,則 .NET Framework 會忽略在每一個上執行 SOAP 擴充功能的相關步驟。

用戶端準備要求訊息

  1. 用戶端會在 Proxy 類別上叫用方法。

  2. 在用戶端上建立 SOAP 擴充功能的新執行個體。

  3. 如果這是第一次在用戶端上以這個 Web 服務執行 SOAP 擴充功能,則會在用戶端上執行的 SOAP 擴充功能上叫用 GetInitializer 方法。

  4. 叫用 Initialize 方法。

  5. 叫用 ChainStream 方法。

  6. SoapMessageStage 設為 BeforeSerialize,以叫用 ProcessMessage 方法。

  7. 用戶端電腦上的 ASP.NET 會將 Web 服務方法的引數序列化為 XML。

  8. SoapMessageStage 設為 AfterSerialize,以叫用 ProcessMessage 方法。

  9. 用戶端電腦上的 ASP.NET 會透過網路將 Web 訊息傳送至裝載 Web 服務的 Web 伺服器。

伺服器端接收要求訊息並準備回應

  1. Web 伺服器上的 ASP.NET 會接收 SOAP 訊息。

  2. 在 Web 伺服器上建立 SOAP 擴充功能的新執行個體。

  3. 在 Web 伺服器上,如果這是第一次在伺服器端以這個 Web 服務執行 SOAP 擴充功能,則會在伺服器上執行的 SOAP 擴充功能上叫用 GetInitializer 方法。

  4. 叫用 Initialize 方法。

  5. 叫用 ChainStream 方法。

  6. SoapMessageStage 設為 BeforeDeserialize,以叫用 ProcessMessage 方法。

  7. ASP.NET 會還原序列化 XML 中的引數。

  8. SoapMessageStage 設為 AfterDeserialize,以叫用 ProcessMessage 方法。

  9. ASP.NET 會建立實作 Web 服務的類別的新執行個體,而且會傳入還原序列化的引數,以叫用 Web 服務方法。這個物件位在 Web 伺服器的相同電腦上。

  10. Web 服務方法會執行它的程式碼,最後會設定傳回值和任何 out 參數。

  11. SoapMessageStage 設為 BeforeSerialize,以叫用 ProcessMessage 方法。

  12. Web 伺服器上的 ASP.NET 會將傳回值和 out 參數序列化為 XML。

  13. SoapMessageStage 設為 AfterSerialize,以叫用 ProcessMessage 方法。

  14. ASP.NET 會透過網路將 SOAP 回應訊息傳回至 Web 服務用戶端。

用戶端接收回應訊息

  1. 用戶端電腦上的 ASP.NET 會接收 SOAP 訊息。

  2. SoapMessageStage 設為 BeforeDeserialize,以叫用 ProcessMessage 方法。

  3. ASP.NET 會將 XML 還原序列化為傳回值和任何 out 參數。

  4. SoapMessageStage 設為 AfterDeserialize,以叫用 ProcessMessage 方法。

  5. ASP.NET 會將傳回值和任何 out 參數傳遞至 Proxy 類別的執行個體。

  6. 用戶端會接收傳回值和任何 out 參數。

實作 SOAP 擴充功能

有兩種方式可以在用戶端或伺服器應用程式上執行 SOAP 擴充功能。第一,您可以設定應用程式來執行擴充功能。若要針對所有 Web 服務上的所有 Web 方法 (特別是 vroot),設定 SOAP 擴充功能,請編輯 Web.config 檔案中的 <soapExtensionTypes> 項目 區段。下列程式碼中,會示範 type 屬性值必須在同一行,並且包含擴充功能的完整名稱,加上簽署組件的版本、文化特性和公開金鑰權杖。

<configuration>
 <system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="Contoso.MySoapExtension, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
priority="1" group="0"/>
        </soapExtensionTypes>
    </webServices>
  </system.web>
</configuration>

第二,您可以建立自訂屬性並套用至 Web 服務方法。若要建立自訂屬性,請建立衍生自 SoapExtensionAttribute 的類別。如需建立自訂屬性的詳細資訊,請參閱 HOW TO:實作 SOAP 擴充功能。如需建立多個自訂屬性的詳細資訊,請參閱<建立自訂屬性>。

esw638yk.note(zh-tw,VS.100).gif注意:
實作 SOAP 擴充功能時,如果擴充功能使用 XmlTextReader 來讀取資料流,可能會發生阻絕服務 (DOS) 攻擊。防止這類攻擊的一個方法是確定 ProhibitDtd 屬性設為 true

優先權和優先權群組

不論使用屬性或組態,都可以為 SOAP 擴充功能指派優先權,當多個 SOAP 擴充功能設定為以 XML Web Service 方法執行時,有助判斷執行的相對順序。SOAP 擴充功能的優先權越高,對網路上傳送或接收的 SOAP 訊息越快執行此擴充功能。SOAP 擴充功能屬於三個優先權群組的任何一個。在每個群組中,priority 屬性會辨別每個成員。priority 屬性越低,相對優先權越高 (0 是最高)。

SOAP 擴充功能的三個相對優先權群組為:使用屬性設定的 SOAP 擴充功能,以及使用 01group 設定,在組態檔中指定的 SOAP 擴充功能。它們的優先權依序如下:

  • 最高優先權群組:使用 0group 設定,在組態檔中設定的 SOAP 擴充功能。

  • 中等優先權群組:使用屬性設定的 SOAP 擴充功能。

  • 最低優先權群組:使用 1group 設定,在組態檔中設定的 SOAP 擴充功能。

下列程式碼範例中,組態檔會指定 Logger.LoggerExtension SOAP 擴充功能在相對優先權群組 0 中執行,而且此擴充功能的優先權為 1

<configuration>
 <system.web>
   <webServices>
     <soapExtensionTypes>
      <add type="Logger.LoggerExtension,logger"
           priority="1"
           group="0" />
     </soapExtensionTypes>
    </webServices>
 </system.web>
</configuration>

另請參閱

工作

HOW TO:實作 SOAP 擴充功能

參考

SoapExtension
SoapExtensionAttribute
SoapMessageStage
LogicalMethodInfo

概念

使用 SOAP 擴充功能修改 SOAP 訊息
XML Web Service 存留期分析
建置 XML Web Service 用戶端

其他資源

Configuring Applications
使用 ASP.NET 的 XML Web Service