共用方式為


傳訊通訊協定

Windows Communication Foundation (WCF) 通道堆疊採用編碼和傳輸通道,將內部訊息表示轉換成其有線格式,並使用特定傳輸來傳送它。 Web 服務互作性所使用的最常見傳輸是 HTTP,而 Web 服務所使用的最常見編碼方式是 XML 型 SOAP 1.1、SOAP 1.2 和訊息傳輸優化機制 (MTOM)。

本主題涵蓋所採用之下列通訊協定的 HttpTransportBindingElementWCF 實作詳細數據。

規格/檔案:

本主題涵蓋下列通訊協議 TextMessageEncodingBindingElementMtomMessageEncodingBindingElement 採用的 WCF 實作詳細數據。

規格/檔案:

本主題涵蓋下列採用之通訊協定 MtomMessageEncodingBindingElement 的 WCF 實作詳細數據。

規格/檔案:

本主題中會使用下列 XML 命名空間和相關聯的前置詞:

前綴 命名空間統一資源識別碼 (URI)
s11 http://schemas.xmlsoap.org/soap/envelope
s12 http://www.w3.org/2003/05/soap-envelope
wsa http://www.w3.org/2004/08/addressing
wsam http://www.w3.org/2007/05/addressing/metadata
wsap (某軟體或概念的中文名稱) http://schemas.xmlsoap.org/ws/2004/09/policy/addressing
wsa10 http://www.w3.org/2005/08/addressing
wsaw10 http://www.w3.org/2006/05/addressing/wsdl
xop http://www.w3.org/2004/08/xop/include
xmime http://www.w3.org/2004/06/xmlmime

http://www.w3.org/2005/05/xmlmime
dp http://schemas.microsoft.com/net/2006/06/duplex

SOAP 1.1 和 SOAP 1.2

信封和處理模型

WCF 會實作 SOAP 1.1 信封處理,並遵循基本規範 1.1(BP11)與 1.0(SSBP10)。 SOAP 1.2 信封處理是在SOAP12-Part1之後實作。

本節說明 WCF 針對 BP11 和 SOAP12-Part1 所採取的某些實作選擇。

強制標頭處理

WCF 根據 SOAP 1.1 和 SOAP 1.2 規格中所述的規則來處理標記為 mustUnderstand 的標頭,並存在以下變化。

輸入WCF通道堆疊的訊息是由相關聯綁定項所設定的個別通道處理,例如文字訊息編碼、安全性、可靠的傳訊和交易。 每個通道都會辨識相關聯命名空間中的標頭,並將其標示為已瞭解。 一旦訊息進入發送器,作業格式器就會讀取對應訊息/作業合約所預期的標頭,並將其標示為已瞭解。 然後調度器會驗證是否存在任何未理解但已標示為 mustUnderstand 的剩餘標頭,並擲回例外狀況。 收件者應用程式程式代碼不會處理包含 mustUnderstand 收件者目標標頭的郵件。

這類階層處理可讓您在 SOAP 節點的基礎結構層和應用層之間分隔:

  • B1111:在 WCF 基礎結構通道堆疊處理訊息後,但在應用程式處理訊息前,偵測到不被理解的標頭。

    標頭 mustUnderstand 值在 SOAP 1.1 和 SOAP 1.2 之間有所不同。 基本配置檔 1.1 規定 mustUnderstand 在 SOAP 1.1 訊息中的值必須是 0 或 1。 SOAP 1.2 允許 0、1、falsetrue 作為值,但建議使用值的規範表示法,即使用 xs:booleanfalse

  • B1112:WCF 在 SOAP 1.1 和 SOAP 1.2 版本的 SOAP 信封中會發出值 mustUnderstand,這裡mustUnderstand 的值為 0 和 1。 WCF 接受 xs:boolean 標頭的整個值空間 mustUnderstand(0,1,falsetrue

SOAP 錯誤

以下是 WCF 特定 SOAP 錯誤實作的清單。

  • B2121:WCF 會傳回下列 SOAP 1.1 錯誤碼: s11:mustUnderstands11:Clients11:Server

  • B2122:WCF 會傳回下列 SOAP 1.2 錯誤碼: s12:MustUnderstands12:Senders12:Receiver

HTTP 綁定

SOAP 1.1 HTTP 繫結

WCF 會在基本配置檔 1.1 規格第 3.4 節 3.4 之後實作 SOAP1.1 HTTP 系結,並說明下列事項:

  • B2211:WCF 服務不會實作 HTTP POST 要求的重新導向。

  • B2212:WCF 用戶端根據3.4.8支援 HTTPCookie。

SOAP 1.2 HTTP 繫結

WCF 會實作 SOAP 1.2 HTTP 系結,如 SOAP 1.2-part 2 (SOAP12Part2) 規格中所述,並說明下列說明。

SOAP 1.2 引進了媒體類型的選擇性動作參數 application/soap+xml 。 當未使用 WS-Addressing 時,此參數有助於優化訊息分派,而不需要剖析 SOAP 訊息的主體。

  • R2221:當 application/soap+xml 動作參數存在於 SOAP 1.2 要求中時,必須符合對應 WSDL 系結內 soapAction 元素上的 wsoap12:operation 屬性。

  • R2222: application/soap+xml 在 SOAP 1.2 訊息上存在的動作參數,在使用 2004/08 WS-Addressing 或 WS-Addressing 1.0 時必須相符 wsa:Action

停用 WS-Addressing 且傳入要求不包含動作參數時,訊息 Action 被視為未指定。

WS-Addressing

WCF 會實作 3 個版本的 WS 尋址:

  • WS-Addressing 2004/08

  • W3C Web 服務尋址 1.0 核心 (ADDR10-CORE) 和 SOAP 系結 (ADDR10-SOAP)

  • WS-Addressing 1.0 - 元數據

端點參考

WCF 實作的所有 WS-Addressing 版本都會使用端點參考來描述端點。

端點引用與 WS-Addressing 版本

WCF 會實作一些基礎結構通訊協定,這些通訊協定會使用 WS-Addressing,特別是 EndpointReference 專案和 W3C.WsAddressing.EndpointReferenceType 類別(例如 WS-ReliableMessaging、WS-SecureConversation 和 WS-Trust)。 WCF 支援使用 WS-Addressing 的任一版本來搭配其他基礎結構通訊協定。 WCF 端點支援每個端點一個版本的 WS-Addressing。

針對 R3111,與 WCF 端點交換之訊息中使用的元素或型別命名空間 EndpointReference 必須符合此端點所實作之 WS-Addressing 的版本。

例如,如果 WCF 端點實作 WS-ReliableMessaging,在 AcksTo 中這類端點所傳回的 CreateSequenceResponse 標頭會使用 EncodingBinding 元素為此端點指定的 WS-Addressing 版本。

端點參考和元數據

許多情境需要傳遞元數據或指定端點的元數據參考。

B3121:WCF 採用 WS-MetadataExchange (MEX) 規格第 6 節中描述的機制,以依值或參照方式包含端點參考的元數據。

請考慮 WCF 服務需要使用令牌簽發者在 http://sts.fabrikam123.com上發出的安全性判斷提示標記語言 (SAML) 令牌進行驗證的案例。 WCF 端點會使用 sp:IssuedToken 斷言,並以巢狀 sp:Issuer 斷言指向權杖簽發者,來描述此驗證需求。 使用聲明的sp:Issuer 用戶端應用程式必須知道如何與令牌發行者端點通訊。 客戶端必須知道令牌簽發者的元數據。 使用 MEX 中定義的端點參考元數據延伸模組,WCF 會提供令牌頒發者元數據的參考。

<sp:IssuedToken>
  <sp:Issuer>
    <wsa10:Address>
      http://sts.fabrikam123.com
    </wsa10:Address>
    <wsa10:Metadata>
      <mex:Metadata>
        <mex:MetadataSection>
          <mex:MetadataReference>
            <wsa10:Address>
              http://sts.fabrikam123.com/mex
            </wsa10:Address>
          </mex:MetadataReference>
        </mex:MetadataSection>
      </mex:Metadata>
    </wsa10:Metadata>
  </sp:Issuer>
</sp:IssuedToken>

訊息地址標頭

訊息標頭

針對這兩個 WS-Addressing 版本,WCF 會使用下列訊息標頭,如規格wsa:Towsa:ReplyTowsa:Actionwsa:MessageIDwsa:RelatesTo所規定。

B3211:針對所有 WS-Addressing 版本,WCF 會接受 WS-Addressing 訊息標頭 wsa:FaultTowsa:From,但不會在預設情況下產生這些標頭。

與 WCF 應用程式互動的應用程式可以新增這些訊息標頭,WCF 會據以處理它們。

參考參數和屬性

WCF 會根據個別規格實作端點參考參數和參考屬性的處理。

B3221:當設定為使用 WS-Addressing 2004/08 時,WCF 端點不會區分處理參考屬性和參考參數。

訊息交換模式

Web 服務作業調用所涉及的訊息序列稱為 訊息交換模式。 WCF 支援單向、要求-回復和雙工訊息交換模式。 本節會根據所使用的訊息交換模式,釐清訊息處理 WS-Addressing 需求。

在本節中,要求者會傳送第一則訊息,而回應者會接收第一則訊息。

One-Way 訊息

當 WCF 端點設定為支援具有指定 Action 以遵循單向模式的訊息時,WCF 端點會遵循下列行為和需求。 除非另有指定,否則行為和規則適用於 WCF 中支援的兩種 WS-Addressing 版本:

  • R3311:要求者必須包含 wsa:Towsa:Action 和端點參考所指定之所有參考參數的標頭。 使用 WS-Addressing 2004/08 且 [reference properties] 是由端點參考指定時,必須將相應的標頭新增至訊息中。

  • B3312:要求者可能包含 MessageIDReplyToFaultTo 標頭。 接收者基礎結構會忽略它們,而且會傳遞至應用程式。

  • R3313:使用 HTTP 且 HTTP 回應回合上未傳送任何訊息時,回應者必須傳送具有空白本文和 HTTP 202 狀態代碼的 HTTP 回應。

    當 HTTP 傳輸正在使用中,且作業合約宣告單向訊息時,HTTP 回應仍可用於傳送基礎結構訊息,例如,可靠的傳訊可以在 HTTP 回應上傳送 SequenceAcknowledgement 訊息。

  • B3314:WCF 回應程式不會傳送錯誤訊息以回應單向訊息。

Request-Reply

當 WCF 端點設定為具有指定 Action 以遵循要求-回復模式的訊息時,WCF 端點會遵循下列行為和需求。 除非另有指定,否則行為和規則適用於 WCF 中支援的兩種 WS-Addressing 版本:

  • R3321:要求者在請求中必須包含 wsa:Towsa:Actionwsa:MessageID 和所有由端點參考指定的參考參數或參考屬性的標頭(或兩者)。

  • R3322:使用 WS-Addressing 2004/08 時, ReplyTo 也必須包含在要求中。

  • R3323:當使用 WS-Addressing 1.0 且 ReplyTo 不存在於要求中時,會使用等於 http://www.w3.org/2005/08/addressing/anonymous [address] 屬性的默認端點參考。

  • R3324:要求者必須在回復訊息中包含 wsa:Towsa:Actionwsa:RelatesTo 標頭,以及由要求中端點參考 ReplyTo 指定的所有參考參數或參考屬性的標頭(或兩者)。

Web 服務解決錯誤

R3411:WCF 會產生 WS-Addressing 2004/08 定義的下列故障。

程式碼 原因
wsa:DestinationUnreachable 訊息與 ReplyTo 為此通道建立的回復位址不同;在 [收件者] 標頭中指定的位址沒有接聽端點。
wsa:ActionNotSupported 與端點相關聯的基礎結構通道或發送器無法辨識標頭中指定的 Action 動作。

R3412:WCF 會產生 WS-Addressing 1.0 定義的下列錯誤。

程式碼 原因
wsa10:InvalidAddressingHeader 重複wsa:Towsa:ReplyTowsa:Fromwsa:MessageID。 重複 wsa:RelatesTo,使用相同的 RelationshipType
wsa10:MessageAddressingHeaderRequired 遺漏必要的尋址標頭。
wsa10:DestinationUnreachable 訊息到達時,ReplyTo 與為此通道設定的回覆地址不同。 在 To 標頭中指定的位址上沒有接聽的端點。
wsa10:ActionNotSupported 與端點相關聯的基礎結構通道或發送器無法辨識標頭中指定的 Action 動作。
wsa10:EndpointUnavailable RM 通道會將此錯誤傳回,指出端點將不會根據檢查 CreateSequence 這個訊息的尋址標頭來處理序列。

上述表格中的代碼映射至 SOAP 1.1 的 FaultCode 和 SOAP 1.2 的 Code=Sender 的 SubCode

WSDL 1.1 綁定和 WS-Policy 斷言

表示使用 WS-Addressing

WCF 使用原則宣告指出特定 WS-Addressing 版本的端點支援。

下列政策聲明具有端點政策主體 [WS-PA],並指出從端點發送和接收的訊息必須使用 WS-Addressing 2004/08。

<wsap:UsingAddressing />

此政策聲明增強了 WS-Addressing 2004/08 規範。

如下政策聲明表示,傳送/接收的訊息必須使用 WS-Addressing 1.0。

<wsam:Addressing/>

下列政策聲明具有端點政策主題 [WS-PA],並指出從端點傳送和接收的訊息必須使用 WS-Addressing 2004/08。

<wsaw10:UsingAddressing />

元素 wsaw10:UsingAddressing 是從 [WS-Addressing-WSDL] 借用的,並根據該規格第 3.1.2 節,用於WS-Policy的內容。

使用 Addressing 不會改變 WSDL 1.1、SOAP 1.1 和 SOAP 1.2 HTTP 系結的語意。 例如,如果要求是傳送至使用 Addressing 和 WSDL SOAP 1.x HTTP 系結的端點,則回復必須使用 HTTP 回應來傳送。

對於透過 HTTP 回應傳送的回復,WS-AM 判斷提示為:

<wsam:AnonymousResponses/>

完整的政策聲明可能會是這樣:

<wsam:Addressing>
    <wsp:Policy>
        <wsam:AnonymousResponses />
    </wsp:Policy>
</wsam:Addressing>

不過,有消息交換模式可受益於在請求者與應答者之間建立兩個獨立的相反 HTTP 連線,例如,應答者所發送的未經請求的單向消息。

WCF 提供一項功能,其中兩個基礎傳輸通道可以形成複合雙工通道,其中一個通道用於輸入訊息,另一個通道則用於輸出訊息。 在 HTTP 傳輸的情況下,複合雙工會提供兩個相反的 HTTP 連線。 要求者會使用一個連線將訊息傳送給回應者,而回應者則使用另一個連線將訊息傳回要求者。

針對透過個別 HTTP 請求傳送的回復,ws-am 判斷提示為

<wsam:NonAnonymousResponses/>

完整的政策聲明可能會是這樣:

<wsam:Addressing>
    <wsp:Policy>
        <wsam:NonAnonymousResponses />
    </wsp:Policy>
</wsam:Addressing>

在使用 WSDL 1.1 SOAP 1.x HTTP 接合的端點上,使用具有端點策略主體 [WS-PA] 的下列斷言,要求分別使用兩個不同的相反 HTTP 連線,以便從請求者到回應者和從回應者到請求者的訊息流動。

<cdp:CompositeDuplex/>

前述陳述引致要求訊息的 wsa:ReplyTo 標頭需滿足以下要求:

  • R3514:如果端點使用 WSDL 1.1 SOAP 1.x HTTP 系結,而且具有包含ReplyTo[address]http://www.w3.org/2005/08/addressing/anonymous判斷提示,則傳送到端點的要求訊息必須具有wsap10:UsingAddressing 標頭,其屬性不等於wsap:UsingAddressing

  • R3515:如果端點使用 WSDL 1.1 SOAP 1.x HTTP 系結,且有ReplyTo斷言且沒有附加[address]斷言的原則替代方案,則傳送至端點的請求訊息必須具有http://www.w3.org/2005/08/addressing/anonymous標頭,且ReplyTo屬性等於wsap10:UsingAddressing;或者若沒有cdp:CompositeDuplex標頭。

  • R3516:如果端點使用 WSDL 1.1 SOAP 1.x HTTP 系結,並且具有附加了 ReplyTo 斷言但未附加 [address] 斷言的策略替代方案,則傳送至端點的要求訊息必須具有 http://www.w3.org/2005/08/addressing/anonymous 標頭,其 wsap:UsingAddressing 屬性值必須等於 cdp:CompositeDuplex

WS 尋址 WSDL 規格嘗試通過引入一個具有三種文字值(必須、選擇性和禁止)的元素 <wsaw:Anonymous/> 來定義類似通訊協定的系結,以標示在 wsa:ReplyTo 標頭上的需求(第 3.2 節)。 不幸的是,這類元素定義在 WS-Policy 的內容中無法特別作為判斷提示使用,因為它需要網域特定的擴充功能來支援使用這類元素做為判斷提示的替代專案交集。 這類元素定義也會指出標頭的值 ReplyTo ,而不是連線上的端點行為,這使其專屬於 HTTP 傳輸。

動作定義

WS-Addressing 2004/08 定義 wsa:Action 元素的一個 wsdl:portType/wsdl:operation/[wsdl:input | wsdl:output | wsdl:fault] 屬性。 WS-Addressing 1.0 WSDL 系結 (WS-ADDR10-WSDL) 會定義類似的屬性 wsaw10:Action

這兩者的唯一差異是預設的動作模式語意,分別描述於 WS-ADDR 的第 3.3.2 節和 WS-ADDR10-WSDL 的第 4.4.4 節。

有兩個端點共用相同的 portType(或在 WCF 術語中的合約),但使用不同版本的 WS-Addressing 是合理的。 但是,假設動作是由portType定義的,並且不應該在實作portType的端點之間變更,因此無法支援這兩種默認動作模式。

為了解決這個爭議,WCF 支援單一版本的 Action 屬性。

B3521:不論端點所使用的是哪個版本的 WS-Addressing,WCF 會使用 WS-ADDR10-WSDL 中所定義元素上的 wsaw10:Action 屬性,來判斷 wsdl:portType/wsdl:operation/[wsdl:input | wsdl:output | wsdl:fault] 對應訊息的 URI。

在 WSDL 埠中使用端點參考

WS-ADDR10-WSDL 區段 4.1 擴充 wsdl:port 元素,以加入 <wsa10:EndpointReference…/> 子元素,以 WS-Addressing 詞彙描述端點。 WCF 會於 WS-Addressing 2004/08 擴展此公用程式,允許 <wsa:EndpointReference…/> 顯示為 wsdl:port 的子專案。

  • R3531:如果端點具有附加的策略替代方案與 <wsaw10:UsingAddressing/> 策略判斷提示,對應的 wsdl:port 元素可以包含子元素 <wsa10:EndpointReference …/>

  • R3532:如果 wsdl:port 包含子專案,子<wsa10:EndpointReference …/>專案wsa10:EndpointReference/wsa10:Address值必須符合@address同層級wsdl:port/wsdl:location元素的 屬性值。

  • R3533:如果端點具有附加政策替代方案和 <wsap:UsingAddressing/> 政策斷言,則相應的 wsdl:port 元素可以包含子元素 <wsa:EndpointReference …/>

  • R3534:如果 wsdl:port 包含子專案 <wsa:EndpointReference …/>,子 wsa:EndpointReference/wsa:Address 專案值必須符合 @address 同層級 wsdl:port/wsdl:location 元素的 屬性值。

使用 WS-Security 撰寫

根據 WS-ADDR 和 WS-ADDR10 中的安全性考慮區段,建議將所有尋址訊息標頭與訊息本文一起簽署,以將它們系結在一起。

當 WS-Security 用於訊息完整性保護時,WS-Addressing 訊息標頭以及參考參數或屬性所產生的標頭(或兩者)都必須與訊息本文一起簽署。

範例

One-Way 訊息

在此案例中,傳送者會將單向訊息傳送給接收者。 使用SOAP 1.2、HTTP 1.1和 W3C WS-Addressing 1.0。

要求訊息結構:訊息標頭包含 wsa10:Towsa10:Action 元素。 訊息本文包含來自應用程式命名空間的特定 <app:Ping> 元素。

HTTP 標頭:POST 中的目的地符合 元素中的 wsa10:To URI。

Content-Type 標頭具有 SOAP 1.2 所需的值 application/soap+xml 。 參數 charsetaction 都包含在內。 action Content-Type 標頭的參數符合訊息標頭的值wsa10:Action

POST http://fabrikam123.com/Service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8;  
              action="http://fabrikam123.com/Service/OneWay"
Host: 131.107.72.15
Content-Length: 1501
Expect: 100-continue
Proxy-Connection: Keep-Alive
<s12:Envelope>
  <s12:Header>
    <wsa10:To s12:mustUnderstand="1">
        http://fabrikam123.com/Service
    </wsa10:To>
    <wsa10:Action s12:mustUnderstand="1">
        http://fabrikam123.com/Service/OneWay
    </wsa10:Action>
  </s12:Header>
  <s12:Body>
    <Ping xmlns="http://fabrikam123.com/Service/">
      <Text>Hello World</Text>
    </Ping>
  </s12:Body>
</s12:Envelope>

接收者會以空的 HTTP 回應和狀態 202 回應。 HTTP 回應的範例:

HTTP/1.1 202 Accepted
Date: Fri, 15 Jul 2005 08:56:07 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50215
Cache-Control: private
Content-Length: 0

SOAP 訊息傳輸優化機制

本節說明 HTTP SOAP MTOM 的 WCF 實作詳細數據。 MTOM 技術是與傳統文字/XML 編碼或 WCF 二進位編碼相同類別的 SOAP 訊息編碼機制。 MTOM 包含下列專案:

  • [XOP] 所描述的 XML 編碼和封裝機制,可將包含base64編碼二進位數據的 XML 資訊專案優化為個別的二進位元件。

  • XOP 套件的 MIME 封裝,將 XML 資訊集以及 XOP 套件中的每個二進位元件,分別串行化為各自的 MIME 元件。

  • MIME XOP 編碼已套用至 SOAP 1.x 信封。

  • HTTP 傳輸系結。

您可以透過 WCF 使用 MTOM 搭配非 HTTP 的傳輸協定。 不過,在本主題中,我們將著重於 HTTP。

MTOM 格式會利用一組涵蓋 MTOM 本身、XOP 和 MIME 的大型規格。 此規格集的模組化讓重新建構格式和處理語意的確切需求有點困難。 本節說明 MTOM HTTP 系結的格式和處理需求。

MTOM 訊息編碼

產生 MTOM 訊息

[XOP] 第 3.1 節描述將包含 base64 值的元素資訊項目編碼成 XML 的過程,然後編成抽象定義的 XOP 套件。

下列步驟順序描述 MTOM 特定的編碼程式:

  1. 請確保要進行編碼的 SOAP Envelope 不包含任何帶有 [namespace name]http://www.w3.org/2004/08/xop/include[local name]Include 的元素訊息項。

  2. 建立空的MIME套件。

  3. 在原始 XML Infoset 內識別要優化的元素信息項目。 若要將專案優化,組成 [children] 元素信息專案的字元必須採用標準格式 xs:base64Binary (請參閱 XSD-2,3.2.16 base64Binary),且不得包含之前、內嵌或遵循非空格符內容的任何空格符。

  4. 建立一個 XOP SOAP 信封,這是原始 SOAP 信封的複本,但用如以下所示建構的 xop:Include 元素資訊專案取代先前步驟中所識別的每個元素資訊專案的子項。

    1. 將已取代的字元轉換成二進位數據,方法是將它們當作base64編碼的數據來處理。

    2. 產生符合 R3133 和 R3134 需求的唯一 Content-ID 標頭值。

    3. 使用二進位值產生 Content-Transfer-Encoding MIME 標頭。

    4. 如果要優化的元素信息項(新插入 xop:Include 元素信息項的 [父項]),並且具有 xmime:contentType 屬性信息項,請產生具有該屬性值的 Content-Type MIME 標頭。

    5. 產生新的二進位MIME元件,內容由解碼自已取代字元的二進位數據構成,這些字元被處理為base64。此外,包含來自步驟4b的Content-ID標頭、步驟4c的Content-Transfer-Encoding標頭,以及如步驟4d中有產生則包含Content-Type標頭。

    6. 新增屬性到href元素,該屬性值為從步驟 4b 中產生的 Content-ID 標頭值衍生出的 cid: uri。 移除包圍的標籤 "<" 和 ">",將剩餘的字串轉換為 URL 編碼,然後新增前綴 cid:。 RFC1738和RFC2396必須逸出下列最小字元集。 其他字元可以逸出。

      Hexadecimal 00-1F , 7F, 20, "<" | ">" | "#" | "%" | <">
      "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" | "~" | "^"
      
  5. 使用步驟 4 中的 XOP SOAP Envelope 建立根 MIME 元件。

  6. 撰寫 HTTP 標頭,包括 HTTP Content-Type 標頭。

  7. 撰寫MIME套件。

處理 MTOM 訊息

MTOM 訊息的處理與先前「產生 MTOM 訊息」一節中所述的程式完全相反:

  1. 確定根 MIME 元件具有 Content-Type application/xop+xml

  2. 藉由將封裝的根MIME部分剖析為 XML 檔,以建構SOAP Envelope。 字元編碼是由 charset 根MIME元件的 Content-Type 參數所決定。

  3. 針對建構的 SOAP Envelope 中的每個元素資訊項目,當其 [children] 屬性只有一個成員,即 xop:Include 元素資訊項目時:

    1. 移除cid:前置詞並對@href元素中的xop:Include屬性值內的所有 URI 逸出序列(RFC 2396)進行反編碼。 將結果字串括在 “<”、“”> 中。

    2. 找出符合步驟 3a 中衍生字串之 Content-ID 標頭值的 MIME 元件。

    3. 用代表標準Base64編碼的字元信息項目取代出現在每個專案的屬性中的xop:Include元素信息項目(請參閱 XSD-2, 3.2.16 base64Binary),此編碼為步驟3b中識別的MIME部分的實體主體編碼(實際上是用從包裹部分重建的數據取代children元素信息項目)。

HTTP 內容類型標頭

以下是 WCF 厘清清單,說明 SOAP 1.x MTOM 編碼訊息格式的格式,這些訊息衍生自 MTOM 規格本身中所述的需求,且衍生自 MTOM 和 RFC 2387。

  • R4131:HTTP Content-Type 標頭必須具有多部分/相關(不區分大小寫)及其參數的值。 參數名稱不區分大小寫。 參數順序不重要。

  • MIME 訊息內容類型標頭的完整 Backus-Naur 表單 (BNF) 列在 RFC 2045 第 5.1 節中。

  • R4132:HTTP Content-Type 標頭必須具有以雙引弧括住的值 application/xop+xml 的類型參數。

雖然使用雙引號的需求在 RFC 2387 中並不明確,但文字會觀察到,所有多部分/相關媒體類型參數最有可能包含 “@” 或 “/” 等保留字元,因此需要雙引號。

  • R4133:HTTP Content-Type 標頭應該包含一個起始參數,其值為包含 SOAP 1.x Envelope 的 MIME 部分的 Content-ID 標頭,並以雙引號括住。 如果省略 start 參數,則第一個 MIME 元件必須包含 SOAP 1.x Envelope。

  • R4134:SOAP 1.1 MTOM 編碼訊息的 HTTP 內容類型標頭必須包含 start-info 參數與文字/xml 的值,並以雙引號括住。

  • R4135:SOAP 1.2 MTOM 編碼訊息的 HTTP 內容類型標頭必須包含 start-info 參數,其值為 application/soap+xml,並以雙引號括住。

  • R4136:SOAP 1.x MTOM 編碼訊息的 HTTP 內容類型標頭必須具有界限參數,其值(以雙引弧括住)符合 RFC 2046 中定義的 MIME 界限 BNF,第 5.1.1 節

    boundary := 0*69<bchars> bcharsnospace
    bchars := bcharsnospace / " "
    bcharsnospace :=    DIGIT / ALPHA / "'" / "(" / ")" / "+"
                        / "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
    

    範例:

    正確

    Content-Type: multipart/related; type="application/xop+xml";start=" <part0@tempuri.org>";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1";start-info="text/xml"
    

    正確

    Content-Type: Multipart/Related; type="application/xop+xml";start-info="text/xml";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1"
    

    不對

    Content-Type: Multipart/Related; type=application/xop+xml;start=" <part0@tempuri.org>";start-info="text/xml";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1"
    

Infoset MIME 元件

SOAP 1.x Envelope 被封裝為 XOP MIME 套件的根部分,通常稱為 infoset 部分。

  • R4141:SOAP 1.x Envelope 必須封裝為 XOP MIME 套件的根組件,命名為 infoset 元件,並從 HTTP Content-Type 標頭進行參考。

  • R4142:SOAP Infoset 元件必須包含下列 MIME 標頭: Content-IDContent-Transfer-EncodingContent-Type

Content-ID 標頭的格式由 RFC 2045 定義為

"Content-ID" ":" msg-id

其中 msg-id 定義於 RFC 2822(此標準取代 RFC 822,且 RFC 2045 引用了 RFC 822),如下所示:

msg-id    =       [CFWS] "<" id-left "@" id-right ">" [CFWS]

實際上是一個被括在「<」和「>」之內的電子郵件地址。 在 RFC 2822 中新增前綴和後綴以攜帶批注,然而不應用於維持互作性。

R4143:Infoset MIME 元件的 Content-ID 標頭值必須遵循 RFC 2822 的 msg-id 格式,但省略 [CFWS] 前綴和後綴部分。

一些MIME實作放寬了在<和>中括住值需為電子郵件位址的要求,除了電子郵件位址之外,還在absoluteURI和<中括住>。 此版本的 WCF 會使用格式為 Content-ID MIME 標頭的值:

Content-ID: <http://tempuri.org/0>

R4144:MTOM 處理器應該接受內容標識碼值,其中的 Content-ID 標頭值應符合以下較寬鬆的規範 msg-id

msg-id-relaxed =     [CFWS] "<" (absoluteURI | mail-address) ">" [CFWS]
mail-address   =     id-left "@" id-right

MIME (RFC 2045) 提供 Content-Transfer-Encoding 標頭,以傳達 MIME 部分內容的編碼方式。 針對 Content-Transfer-Encoding 定義的預設為 7 位,這不適用於大部分的 SOAP 訊息,因此需要 Content-Transfer-Encoding 標頭,才能提高互作性:

  • R4145:SOAP Infoset 元件必須包含 Content-Transfer-Encoding 標頭。

  • R4146:如果 SOAP Envelope 字元編碼為 UTF-8,Content-Transfer-Encoding 標頭的值必須是 8 位。

  • R4147:如果 SOAP Envelope 字元編碼方式為 UTF-16,Content-Transfer-Encoding 標頭的值必須是二進位。

  • 根據 [XOP] 第 5 節,

  • R4148:SOAP1.1 Infoset 元件必須包含 Content-Type 標頭,該標頭的媒體類型為 application/xop+xml,並具有參數 type="text/xml" 和 charset。

    Content-Type: application/xop+xml;
                  charset=utf-8;type="text/xml"
    
  • R4149:SOAP 1.2 Infoset 元件必須包含 Content-Type 標頭,其中具有媒體類型 application/xop+xml 及參數 type="application/soap+xml" 和 charset

    Content-Type: application/xop+xml;
                  charset=utf-8;type="application/soap+xml"
    

    雖然 XOP 定義 charsetapplication/xop+xml 參數為可選項,但為了符合類似於 BP 1.1 對 charset 媒體類型中 text/xml 參數的要求,需要它以實現互操作性。

  • R41410: typecharset 參數必須存在於SOAP 1.x Infoset 元件的 Content-Type 標頭上。

MTOM 的 WCF 端點支援

MTOM 的目的是編碼 SOAP 訊息,以優化 base64 編碼的數據。 以下是條件約束的清單:

  • R4151:任何包含base64編碼數據的元素資訊項目都可以優化。

  • B4152:WCF 會優化包含 base64 編碼資料且超過 1024 位元組長度的元素資訊項目。

設定為使用 MTOM 的 WCF 端點一律會傳送 MTOM 編碼的訊息。 即使沒有任何元件符合必要準則,訊息仍會以 MTOM 編碼(串行化為 MIME 套件,其中包含 SOAP 信封的單一 MIME 元件)。

MTOM 的 WS-Policy 斷言

WCF 會使用下列政策斷言來標示端點使用 MTOM。

<wsoma:OptimizedMimeSerialization />
  • R4211:前述政策聲明具有端點政策主體,並規定所有傳送到端點和從端點接收的訊息都必須使用 MTOM 進行優化。

  • B4212:當設定為使用MTOM優化時,WCF端點會將MTOM策略主張新增至附加於對應wsdl:binding的策略。

使用 WS-Security 撰寫

MTOM 是類似於 text/xml 和 WCF 二進位 XML 的編碼機制。 MTOM 使用 WS-Security 和其他 WS-* 通訊協定提供自然組合:可以使用 MTOM 優化使用 WS-Security 保護的訊息。

範例

使用 MTOM 編碼的 WCF SOAP 1.1 訊息

POST http://131.107.72.15/Mtom/svc/service.svc/Soap11MtomUTF8 HTTP/1.1
SOAPAction: "http://xmlsoap.org/echoBinaryAsString"
Content-Type: multipart/related;type="application/xop+xml";
              start="<http://tempuri.org/0>";start-info="text/xml";
       boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1"
Host: 131.107.72.15
Content-Length: 1501
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <EchoBinaryAsString xmlns="http://xmlsoap.org/Ping">
      <array>
        <xop:Include
         href="cid:http%3A%2F%2Ftempuri.org%2F1%2F632618206521093670"
         xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
      </array>
    </EchoBinaryAsString>
  </s:Body>
</s:Envelope>
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1
Content-ID: <http://tempuri.org/1/632618206521093670>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
…Binary Content..
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1

使用 MTOM 編碼的 WCF 安全 SOAP 1.2 訊息

在此範例中,訊息會使用使用 WS-Security 保護的 MTOM 和 SOAP 1.2 進行編碼。 為編碼而識別的二進位部分是 BinarySecurityToken 的內容,以及 CipherValueEncryptedData 的內容,它們分別對應至加密簽章和加密主體。 請注意,WCF 未識別 CipherValueEncryptedKey 以進行優化,因為其長度小於 1024 位元組。

POST http://131.107.72.15/Mtom/service.svc/Soap12MtomSecureSignEncrypt HTTP/1.1
Content-Type: multipart/related; type="application/xop+xml";
              start="<http://tempuri.org/0>";
            boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3";
              start-info="application/soap+xml";
              action="http://xmlsoap.org/echoBinaryAsString"
Host: 131.107.72.15
Content-Length: 1941
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="uuid-4d4ee765-5717-4d53-9ac9-99bddc07df6c-5">
        <u:Created>2005-09-09T06:57:32.488Z</u:Created>
        <u:Expires>2005-09-09T07:02:32.488Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken u:Id="uuid-4d4ee765-5717-4d53-9ac9-99bddc07df6c-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
        <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F1%2F632618206525089430" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
      </o:BinarySecurityToken>
      <e:EncryptedKey Id="_1" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference>
            <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">Xeg55vRyK3ZhAEhEf+YT0z986L0=</o:KeyIdentifier>
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>          <e:CipherValue>oQfpxwT8/SAGyZQzKE2b4yO6dXuQj7pwJ+5CGL3Rf7C06bQ5ttMoQ9GLJcQYkXTzin+WwHEgs5bj5ml9HKTW9QAU5JJ6lksdymmQvWP5ZtGPBVchO4sofEGoCKmBiZL/DYS/cnbzgnc/3a6NYnc10y2fWGaGLiqa00zijAw7o0Y=</e:CipherValue>
        </e:CipherData>
      </e:EncryptedKey>
      <c:DerivedKeyToken u:Id="_2" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
        <o:SecurityTokenReference>
          <o:Reference URI="#_1"/>
        </o:SecurityTokenReference>
        <c:Nonce>OrEPRX7fISIS4sXYWPMv3g==</c:Nonce>
      </c:DerivedKeyToken>
      <e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:DataReference URI="#_3"/>
        <e:DataReference URI="#_4"/>
      </e:ReferenceList>
      <e:EncryptedData Id="_4" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference>
            <o:Reference URI="#_2"/>
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>
          <e:CipherValue>
            <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F2%2F632618206525089430" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
          </e:CipherValue>
        </e:CipherData>
      </e:EncryptedData>
    </o:Security>
  </s:Header>
  <s:Body u:Id="_0">
    <e:EncryptedData Id="_3" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
      <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <o:Reference URI="#_2"/>
        </o:SecurityTokenReference>
      </KeyInfo>
      <e:CipherData>
        <e:CipherValue>
          <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F3%2F632618206525089430" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
        </e:CipherValue>
      </e:CipherData>
    </e:EncryptedData>
  </s:Body>
</s:Envelope>
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/1/632618206525089430>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
...Binary content of BinarySecurityToken - X509 Certificate...
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/2/632618206525089430>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
...Binary serialization of the encrypted primary signature...
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/3/632618206525089430>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
...Binary serialization of the encrypted Body...
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3--