首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 訊息傳輸模式深度解析:緩衝與串流、序列化與反序列化

     編輯:關於.NET

Buffered vs Streamed:兩種訊息傳輸模式

當訊息在端點間流動時,預設直覺為「緩衝模式」——接收端在處理前已完整取得整個訊息。相對地,「串流模式」分為推模型與拉模型,WCF 實作為拉模型:接收端向傳送端請求資料,傳送端回應請求量,循環直到傳輸完成。

WCF 的具體實作細節

  • 訊息標頭:永遠採用緩衝模式。
  • 訊息本文:可選擇 Buffered 或 Streamed,預設緩衝區大小 64KB(第 8 章說明調整)。
  • Streamed 優勢:本文大小理論無上限,適合傳輸大型媒體串流(如 30 分鐘影片),接收端可邊下載邊播放。
  • 不適用場景:需完整資料驗證(如數位簽章)或小型訊息(緩衝更高效)。

訊息序列化:Write 方法族群

所有序列化方法皆以 Write 開頭,接受 XmlWriter 或 XmlDictionaryWriter。實際序列化工作由 Writer 完成,包含「序列化為 XML Infoset」與「編碼為特定格式」兩步驟。

關鍵方法原型

public void WriteStartEnvelope(XmlDictionaryWriter writer);
public void WriteStartBody(XmlDictionaryWriter writer);
public void WriteBody(XmlDictionaryWriter writer);
public void WriteBodyContents(XmlDictionaryWriter writer);
public void WriteMessage(XmlDictionaryWriter writer);
public void WriteMessage(XmlWriter writer);
  • WriteMessage:序列化完整訊息(最常用)。
  • WriteBody:序列化 Body 標籤與內容。
  • WriteBodyContents:僅序列化 Body 內容(無標籤)。
  • WriteStartEnvelope + WriteStartBody:可精細控制,但需自行序列化標頭(下節說明)。
  • 結束標籤需直接呼叫 XmlWriter.WriteEndElement。

訊息反序列化:從位元組還原物件

反序列化即從序列化資料建立 Message 物件。核心在於 GetBody<T>() 泛型方法:

public T GetBody<T>();
public T GetBody<T>(XmlObjectSerializer serializer);
  • 將本文內容反序列化為型別 T。
  • 第二個多載接受自訂序列化器,提供擴充點。
  • 型別不匹配將拋出 SerializationException。

偵測 SOAP Fault:IsFault 屬性

Message 可能代表一般 SOAP 訊息或 SOAP Fault。接收端反序列化後,第一件事通常是檢查 IsFault 唯讀屬性,以決定後續處理路徑。

程式碼示範

private static void CreateAndShowMessage(MessageFault messageFault, MessageVersion version) {
    Message message = Message.CreateMessage(version, messageFault, "urn:SomeFaultAction");
    MemoryStream stream = new MemoryStream();
    XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, null, null, false);
    message.WriteMessage(writer); writer.Flush(); stream.Position = 0;

    XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, new XmlDictionaryReaderQuotas());
    message = Message.CreateMessage(reader, Int32.MaxValue, version);

    Console.WriteLine("the message {0} a SOAP Fault", message.IsFault ? "is" : "is not");
}

無論編碼與版本如何,IsFault 均能正確識別 SOAP Fault,展現 WCF 版本無關的設計優勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved