當訊息在端點間流動時,預設直覺為「緩衝模式」——接收端在處理前已完整取得整個訊息。相對地,「串流模式」分為推模型與拉模型,WCF 實作為拉模型:接收端向傳送端請求資料,傳送端回應請求量,循環直到傳輸完成。
所有序列化方法皆以 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。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 版本無關的設計優勢。