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

WCF 系列(五)深入序列化(下):DataContractSerializer 完整實戰

     編輯:關於.NET

WCF 預設序列化器為 DataContractSerializer(DCS),支援類型豐富、效能優異、互操作性強。本文系統整理支援類型、屬性參數、三種序列化寫入器(Text/MTOM/Binary)與程式碼實戰。

一、DCS 支援的六大類型類別

類別說明
[DataContract] 標記型別專為 DCS 設計,支援最完整
.NET 原生型別Byte, Int16, String, DateTime, Guid, Uri 等
[Serializable] 標記型別傳統 Remoting 型別,DCS 完全相容
列舉型別直接序列化為值名稱
XML 直呈型別XmlElement, XmlNode, DataTable, DataSet 等直接輸出 XML
集合型別可序列化型別組成的集合(List<T>, Array, Dictionary 等)

特殊情況:成員含 [XmlAttribute] 等細粒度 XML 控制屬性時,WCF 改用 XmlSerializer,可在方法/契約加 [XmlSerializerFormat] 強制指定。

二、定義 DataContract 型別

[DataContract(Namespace = "https://chnking")]
class Person {
    [DataMember(Order = 0, EmitDefaultValue = true)]
    public Name Name { get; set; }
    [DataMember(Order = 1)]
    public Address Address { get; set; }
    [DataMember(Order = 2)]
    public int Age { get; set; }
    [DataMember] public byte[] BinaryBuffer1 { get; set; } // 20 bytes
    [DataMember] public byte[] BinaryBuffer2 { get; set; } // 768 bytes
}

[DataContract(Namespace = "https://chnking")]
class Name {
    [DataMember] public string Firstname { get; set; }
    [DataMember] public string Lastname { get; set; }
}

[DataContract(Namespace = "https://chnking")]
class Address {
    [DataMember] public string City { get; set; }
    [DataMember] public string Postcode { get; set; }
    [DataMember] public string Street { get; set; }
}

屬性參數重點:

  • Name/Namespace:控制 XML 元素名稱與命名空間
  • Order:序列化順序(無 Order 者優先輸出)
  • EmitDefaultValue:預設值是否序列化(true 輸出 xsi:nil="true")
  • IsRequired:反序列化時是否必須存在

三、三種序列化寫入器實戰

實例化 Person 物件,BinaryBuffer1=20 bytes 'A',BinaryBuffer2=768 bytes 'B'。

1. WriteObject(Stream) → 純文字 UTF-8 + Base64

var dcs = new DataContractSerializer(typeof(Person));
var ms = new MemoryStream();
dcs.WriteObject(ms, person); // 直接寫入 Stream,內部 UTF-8 編碼
// 二進位資料全轉 Base64 字串,無論長短
// 反序列化:ms.Position=0; dcs.ReadObject(ms);

特點:簡單、固定 UTF-8、二進位全 Base64(長資料膨脹 33%)。

2. XmlDictionaryWriter.CreateTextWriter → 可選編碼

var xdw = XmlDictionaryWriter.CreateTextWriter(ms, Encoding.UTF8); // 或 Unicode
dcs.WriteObject(xdw, person);
xdw.Flush();
// 反序列化需對應 CreateTextReader(ms, Encoding.UTF8, quotas, onClose)

結果同方法 1,但可選 Encoding.Unicode/BigEndianUnicode。

3. XmlDictionaryWriter.CreateMtomWriter → MTOM 附件優化大型二進位

var xdw = XmlDictionaryWriter.CreateMtomWriter(ms, Encoding.UTF8, 2048000, "text/xml");
dcs.WriteObject(xdw, person);
xdw.Flush();
// 反序列化:CreateMtomReader(ms, Encoding.UTF8, XmlDictionaryReaderQuotas.Max)

MTOM 機制:

  • 小於 768 bytes 二進位 → 仍內嵌 Base64
  • ≥ 768 bytes → 剝離為 MIME 附件(application/octet-stream),XML 中留 <xop:Include href="cid:..."/>

測試 768 bytes 閾值:767 bytes 內嵌 Base64,768 bytes 拆為附件。有效避免大型二進位 Base64 膨脹。

MTOM MIME 結構 767 bytes 內嵌對比

4. XmlDictionaryWriter.CreateBinaryWriter → .NET 專用二進位最高效

var xdw = XmlDictionaryWriter.CreateBinaryWriter(ms);
dcs.WriteObject(xdw, person);
xdw.Flush();
// 反序列化:CreateBinaryReader(ms, quotas)

輸出不可讀二進位,長度最短(測試 1010 bytes vs Text UTF-8 1385 bytes)。僅限 .NET 環境互通。

二進位輸出強制解碼

四、總結選擇指南

編碼方式互操作性二進位處理適用場景
Text (UTF-8/Unicode)最佳全 Base64一般訊息、跨平台
MTOM良好 (WS-I 標準)大檔拆附件含大型二進位(圖片、文件)
Binary無 (.NET only)原生二進位高效能內部通訊

DCS 核心職責:物件 → XML Infoset;編碼交給 XmlDictionaryWriter 實現多樣化輸出。

原始碼下載:文末附連結。

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