訊息交換是 WCF 通訊的唯一手段。方法呼叫須轉為訊息、經編碼後透過傳輸通道發送;服務執行結果亦須封裝為訊息返回。訊息處於 WCF 架構核心,整個框架可視為一個訊息處理管道。儘管開發者面向介面與物件,但深入理解訊息處理流程,是撰寫高品質程式與靈活擴展 WCF 的前提。
Message.Version 決定訊息格式與結構,由 SOAP 版本與 WS-Addressing 版本共同決定:
EnvelopeVersion:None(非 SOAP,如 JSON/POX)、Soap11、Soap12AddressingVersion:None、WSAddressingAugust2004、WSAddressing10MessageVersion.CreateVersion(envelope, addressing) 組合產生預設組合屬性:Soap11WSAddressing10、Soap12WSAddressing10、None、Soap11、Soap12 等。Default 目前為 Soap12WSAddressing10。注意 EnvelopeVersion.None 不能搭配 Addressing 版本。
Message 為抽象類,靜態 CreateMessage 多載可歸納為五類:
Message.CreateMessage(MessageVersion version, string action)
僅含 Action Header。MessageVersion.None 時不包含 Action,Body 為空。
Message.CreateMessage(version, action, object body)
預設用 DataContractSerializer 序列化。SOAP 版本下 Body 包裝於 <s:Body>;MessageVersion.None 則直接輸出物件 XML(POX)。
範例: Order 資料契約序列化後的 SOAP 與 POX 對比。
Message.CreateMessage(version, action, BodyWriter body)
BodyWriter 為抽象類,覆寫 OnWriteBodyContents(XmlDictionaryWriter)。範例實作 XmlReaderBodyWriter 從 XML 檔讀取內容推入 Body。
Message.CreateMessage(version, action, XmlReader body)
透過 XmlReader(或 XmlDictionaryReader)拉取 XML 內容作為 Body。另兩個多載接受整個 Envelope Reader。
Message.CreateMessage(version, MessageFault fault, string action) Message.CreateMessage(version, FaultCode faultCode, string reason, string action) Message.CreateMessage(version, FaultCode faultCode, string reason, object detail, string action)
FaultCode 包含 Name、Namespace、SubCode(巢狀結構),靜態方法 CreateSenderFaultCode/CreateReceiverFaultCode 便捷建立預定義錯誤。FaultCode.IsPredefinedFault 判斷是否為標準 Fault(如 Sender/Receiver/MustUnderstand)。
範例: 建立包含 SubCode 的 Sender Fault,生成標準 SOAP Fault 結構。
掌握五種建立模式,可應對從簡單 RPC 到複雜訊息級程式設計的各種場景,也是實作自訂編碼器、訊息檢查器的基礎。