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

C# 程式設計總結(一):序列化技術全解析——Binary、XML、JSON、DataContract

     編輯:關於C#

前言

序列化將物件狀態轉為可儲存/傳輸格式(位元組流、XML、JSON),反序列化則還原物件。.NET 提供多種序列化器,各有適用場景。本文系統比較 `BinaryFormatter`、`SoapFormatter`、`XmlSerializer`、`DataContractSerializer`、`DataContractJsonSerializer`,並提供通用輔助類。

主要序列化技術比較

序列化器輸出格式特點適用場景
BinaryFormatter二進位保留型別保真度、私有欄位、物件圖參考;版本容錯弱.NET 內部通訊、剪貼板、Remoting
SoapFormatterSOAP XML開放標準、支援 RPC;較冗長Web Service 舊版、跨平台舊系統
XmlSerializerXML僅公開屬性/欄位、可控制 XML 結構、不保留型別Web API、設定檔、跨平台資料交換
DataContractSerializerXML/JSONWCF 預設、支援版本容錯、需標記 DataContract/DataMemberWCF 服務、現代 .NET 應用
DataContractJsonSerializerJSON輕量、適合 AJAX/前端互動Web API、前後端分離

關鍵用法重點

1. BinaryFormatter

類別標記 `[Serializable]`。`[NonSerialized]` 排除欄位。`[OnSerializing]` 等屬性掛鉤序列化前後邏輯。實作 `ISerializable` 完全控制。

2. XmlSerializer

僅序列化 public 讀寫屬性/欄位。`[XmlIgnore]` 忽略。`[XmlAttribute]`、`[XmlElement]` 控制輸出。可用 `XmlAttributeOverrides` 覆蓋預設映射。

3. DataContractSerializer

類別加 `[DataContract]`,成員加 `[DataMember]`(不限存取修飾詞)。已知型別集合處理多型。支援 `IExtensibleDataObject` 實現版本容錯(往返未知資料保留)。

4. DataContractJsonSerializer

用法同 `DataContractSerializer`,輸出 JSON。注意日期格式 (`/Date(1234567890)/`)。

通用序列化輔助類

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
using System.Text;

public sealed class SerializeHelper {
    #region DataContract (XML)
    public static string SerializeDataContract(object value, List knownTypes = null) {
        var ser = new DataContractSerializer(value.GetType(), knownTypes);
        using (var ms = new MemoryStream()) {
            ser.WriteObject(ms, value);
            ms.Position = 0;
            using (var sr = new StreamReader(ms)) return sr.ReadToEnd();
        }
    }
    public static T DeserializeDataContract(string xml) {
        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))) {
            var ser = new DataContractSerializer(typeof(T));
            return (T)ser.ReadObject(ms);
        }
    }
    #endregion

    #region DataContract JSON
    public static string SerializeDataContractJson(object value) {
        var ser = new DataContractJsonSerializer(value.GetType());
        using (var ms = new MemoryStream()) {
            ser.WriteObject(ms, value);
            return Encoding.UTF8.GetString(ms.ToArray());
        }
    }
    public static T DeserializeDataContractJson(string json) {
        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) {
            var ser = new DataContractJsonSerializer(typeof(T));
            return (T)ser.ReadObject(ms);
        }
    }
    #endregion

    #region XmlSerializer
    public static string SerializeXml(object value) {
        var ser = new XmlSerializer(value.GetType());
        using (var ms = new MemoryStream()) {
            ser.Serialize(ms, value);
            ms.Position = 0;
            using (var sr = new StreamReader(ms)) return sr.ReadToEnd();
        }
    }
    public static object DeserializeXml(Type type, string xml) {
        var ser = new XmlSerializer(type);
        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))) {
            return ser.Deserialize(ms);
        }
    }
    #endregion

    #region BinaryFormatter
    public static string SerializeBinaryFormatter(object obj) {
        var fmt = new BinaryFormatter();
        using (var ms = new MemoryStream()) {
            fmt.Serialize(ms, obj);
            return Encoding.Default.GetString(ms.ToArray()); // 二進位轉字串僅為展示,實際傳輸建議用 byte[]
        }
    }
    public static T DeserializeBinaryFormatter(string str) {
        var fmt = new BinaryFormatter();
        using (var ms = new MemoryStream(Encoding.Default.GetBytes(str))) {
            return (T)fmt.Deserialize(ms);
        }
    }
    #endregion

    #region SoapFormatter
    public static string SerializeSoapFormatter(object obj) {
        var fmt = new SoapFormatter();
        using (var ms = new MemoryStream()) {
            fmt.Serialize(ms, obj);
            return Encoding.UTF8.GetString(ms.ToArray());
        }
    }
    public static T DeserializeSoapFormatter(string str) {
        var fmt = new SoapFormatter();
        using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(str))) {
            return (T)fmt.Deserialize(ms);
        }
    }
    #endregion
}

範例:DataContract 完整示範

[DataContract(Name="Customer", Namespace="https://contoso.com")]
class Person : IExtensibleDataObject {
    [DataMember] public string FirstName;
    [DataMember] public string LastName;
    [DataMember] public int ID;
    public ExtensionDataObject ExtensionData { get; set; } // 版本容錯
}

// 序列化
Person p = new Person { FirstName="Zighetti", LastName="Barbara", ID=101 };
var ser = new DataContractSerializer(typeof(Person));
ser.WriteObject(fileStream, p);

// 反序列化
Person p2 = (Person)ser.ReadObject(xmlReader);

完整原始碼下載:SerializerSample.rar

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