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

WCF 序列化機制全比較:DataContract、Xml、JSON、Soap、Binary 五大序列化器特性與效能

     編輯:關於.NET

WCF 透過序列化將物件圖轉換為傳輸格式,支援多種序列化器,各有適用場景。本文詳細比較 DataContractSerializer、XmlSerializer、DataContractJsonSerializer、SoapFormatter、BinaryFormatter 五大序列化器的特性、輸出格式與效能特徵。

五大序列化器快速比較

序列化器命名空間輸出格式效能版本容忍度適用場景
DataContractSerializerSystem.Runtime.SerializationXML (Infoset)高優 (選擇性欄位)WCF 預設、一般用途
XmlSerializerSystem.Xml.SerializationXML (完整控制)中良需精確控制 XML 結構、相容舊 ASMX
DataContractJsonSerializerSystem.Runtime.Serialization.JsonJSON高優AJAX、REST API、Web 前端
SoapFormatterSystem.Runtime.Serialization.Formatters.SoapSOAP XML低差.NET Remoting、舊版相容
BinaryFormatterSystem.Runtime.Serialization.Formatters.Binary二進位最高差.NET 內部通訊、效能極致場景

實體類別定義與屬性標記

DataContract / DataMember

[DataContract(Namespace = "https://webabcd.cnblogs.com/")]
public class DataContractSerializerObject {
    [DataMember(Name = "UniqueID", Order = 0)] public Guid ID { get; set; }
    [DataMember(Order = 1)] public string Name { get; set; }
    [DataMember(Order = 2)] public int Age { get; set; }
    [DataMember(Order = 3)] public DateTime Time { get; set; }
}
  • Namespace:XML 命名空間
  • Name:序列化後的元素名稱
  • Order:序列化順序 (字母序預設)
  • IsRequired、EmitDefaultValue 等進階選項

XmlSerializer 屬性

[XmlRoot(Namespace = "https://webabcd.cnblogs.com/")]
public class XmlSerializerObject {
    [XmlElement(ElementName = "UniqueID", Order = 0)] public Guid ID { get; set; }
    [XmlElement(Order = 1)] public string Name { get; set; }
    [XmlElement(Order = 2)] public int Age { get; set; }
    [XmlElement(Order = 3)] public DateTime Time { get; set; }
}

JSON 序列化

[DataContract(Namespace = "https://webabcd.cnblogs.com/")]
public class DataContractJsonSerializerObject {
    [DataMember(Name = "UniqueID", Order = 0)] public Guid ID { get; set; }
    [DataMember(Order = 1)] public string Name { get; set; }
    [DataMember(Order = 2)] public int Age { get; set; }
    [DataMember(Order = 3)] public DateTime Time { get; set; }
}

Soap/Binary Formatter:只需 [Serializable]

[Serializable]
public class SoapFormatterObject {
    public Guid ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime Time { get; set; }
}

序列化/反序列化程式碼範例

DataContractSerializer

var obj = new DataContractSerializerObject { 
    ID = Guid.NewGuid(), Name = "DataContractSerializer", Age = 28, Time = DateTime.Now 
};
var serializer = new DataContractSerializer(typeof(DataContractSerializerObject));

// 序列化
var ms = new MemoryStream();
serializer.WriteObject(ms, obj);
ms.Position = 0;
string xml = new StreamReader(ms).ReadToEnd();

// 反序列化
var buffer = Encoding.UTF8.GetBytes(xml);
var ms2 = new MemoryStream(buffer);
var obj2 = serializer.ReadObject(ms2) as DataContractSerializerObject;

XmlSerializer

var serializer = new XmlSerializer(typeof(XmlSerializerObject));
serializer.Serialize(ms, obj); // 序列化
var obj2 = serializer.Deserialize(ms2) as XmlSerializerObject; // 反序列化

SoapFormatter

var formatter = new SoapFormatter();
formatter.Serialize(ms, obj);
string soap = Encoding.UTF8.GetString(ms.GetBuffer());
var obj2 = formatter.Deserialize(ms2) as SoapFormatterObject;

BinaryFormatter

var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
byte[] binary = ms.GetBuffer(); // 二進位位元組陣列
var obj2 = formatter.Deserialize(ms2) as BinaryFormatterObject;

DataContractJsonSerializer

var serializer = new DataContractJsonSerializer(typeof(DataContractJsonSerializerObject));
serializer.WriteObject(ms, obj);
string json = new StreamReader(ms).ReadToEnd();
var obj2 = serializer.ReadObject(ms2) as DataContractJsonSerializerObject;

實際輸出格式比較

DataContractSerializer (XML)

<DataContractSerializerObject xmlns="https://webabcd.cnblogs.com/" xmlns:i="https://www.w3.org/2001/XMLSchema-instance">
  <UniqueID>86148742-ef08-4d78-acab-ce393ea8b885</UniqueID>
  <Name>DataContractSerializer</Name>
  <Age>28</Age>
  <Time>2008-04-24T09:06:23.875+08:00</Time>
</DataContractSerializerObject>

XmlSerializer (XML)

<?xml version="1.0"?>
<XmlSerializerObject xmlns:xsi="..." xmlns:xsd="..." xmlns="https://webabcd.cnblogs.com/">
  <UniqueID>15efa47f-9532-4e91-8c00-3097ea976106</UniqueID>
  <Name>XmlSerializer</Name>
  <Age>28</Age>
  <Time>2008-04-24T09:06:24.109375+08:00</Time>
</XmlSerializerObject>

SoapFormatter (SOAP XML)

<SOAP-ENV:Envelope ...>
  <SOAP-ENV:Body>
    <a1:SoapFormatterObject id="ref-1" ...>
      <_x003C_ID_x003E_k__BackingField>...</_x003C_ID_x003E_k__BackingField>
      <_x003C_Name_x003E_k__BackingField>ShowSoapFormatter</_x003C_Name_x003E_k__BackingField>
      ...
    </a1:SoapFormatterObject>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

BinaryFormatter (二進位,Base64 顯示)

AAEAAAD/////AQAAAAAAAAAMAgAAAFdDRi5TZXJ2aWNlTGliLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAUBAAAIQ1dGLlNlcnZpY2VMaWIuU2VyaWFsaXphdGlvbi5CaW5hcnlGb3JtYXR0ZXJPYmplY3QEAAAAHgQAAAAJAwAAAAcICQg=

DataContractJsonSerializer (JSON)

{"UniqueID":"f4173d7d-9555-4dcb-8db7-62b85315d3f1","Name":"DataContractJsonSerializer","Age":28,"Time":"\/Date(1208999184531+0800)\/"}

關鍵差異深度分析

版本容忍度

  • DataContract/JSON:IsRequired=false (預設) 允許缺少欄位;EmitDefaultValue=false 可省略預設值;支援 OnSerializing/OnDeserialized 回調
  • XmlSerializer:需標記 XmlElement(IsNullable=true) 或使用 DefaultValue 屬性
  • Soap/Binary:嚴格要求欄位完全相容,新增/移除欄位會導致反序列化失敗

效能特徵

  • BinaryFormatter:體積最小、速度最快,但輸出不可讀、跨平台差
  • DataContractSerializer:針對 WCF 優化,流式處理、支援 XML 讀寫器
  • XmlSerializer:啟動時需動態生成序列化組件 (sgen.exe 可預編譯)
  • SoapFormatter:冗長 SOAP 封裝,效能最差,已淘汰

安全性考量

  • BinaryFormatter/SoapFormatter:極度危險,反序列化任意型別可導致 RCE (CVE-2017-0213 等),生產環境嚴禁使用
  • DataContract/JSON/Xml:僅反序列化已知型別,相對安全

選型建議

場景推薦序列化器
WCF 服務間通訊 (預設)DataContractSerializer
REST API / AJAX 前端DataContractJsonSerializer / System.Text.Json
需精確控制 XML 結構 (XSD 驗證)XmlSerializer
高效能 .NET 內部進程通訊BinaryFormatter (僅受信環境) / MessagePack / Protobuf
舊版 .NET Remoting 遷移SoapFormatter (僅相容期使用)

現代化替代方案

.NET Core / .NET 5+ 建議使用:

  • System.Text.Json:高效能 JSON,內建支援,取代 DataContractJsonSerializer
  • MessagePack、Protobuf:二進位高效能,跨語言支援佳
  • XmlSerializer 仍支援但不再是首選

序列化器的選擇直接影響服務的互通性、效能、安全性與維護性,應根據傳輸協定、客戶端類型與版本演進策略綜合評估。

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