定義一個標記 [Serializable] 的類別,其中一個屬性使用傳統 get/set 配合私有欄位實作(非自動屬性):
[Serializable]
public class Users {
public int UserID { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; }
private string _testProperty;
public string TestProperty {
get { return _testProperty; }
set { _testProperty = value; }
}
}
| 序列化器 | 輸出 JSON |
|---|---|
| DataContractJsonSerializer | {"_testProperty":"TestPropertyValue","<UserEmail>k__BackingField":"parry@cnblogs.com","<UserID>k__BackingField":1,"<UserName>k__BackingField":"Parry"} |
| JavaScriptSerializer | {"UserID":1,"UserName":"Parry","UserEmail":"parry@cnblogs.com","TestProperty":"TestPropertyValue"} |
DataContractJsonSerializer 輸出了編譯器生成的後端欄位名稱(k__BackingField),而 JavaScriptSerializer 則正確輸出屬性名稱。
InternalWriteObjectContent 進行嚴格型別檢查,直接序列化物件的所有欄位(包含編譯器為自動屬性生成的 <PropertyName>k__BackingField 私有欄位)。Dictionary,再拼接字串。PropertyInfo,故天然序列化「屬性」而非欄位。[DataContract]
public class Users {
[DataMember] public int UserID { get; set; }
[DataMember] public string UserName { get; set; }
[DataMember] public string UserEmail { get; set; }
[DataMember] public string TestProperty { get; set; } // 改為自動屬性或保留私有欄位並標記
}
明確指定需序列化的成員,輸出乾淨 JSON。
適用於第三方庫或舊版程式碼無法加裝屬性的情境。
| 序列化器 | 適用場景 | 注意事項 |
|---|---|---|
| DataContractJsonSerializer | WCF 服務、嚴格資料合約需求 | 必須加 [DataContract]/[DataMember],否則輸出後端欄位名 |
| JavaScriptSerializer | 簡單 ASP.NET AJAX、無法修改型別定義 | 功能有限、不支援複雜多型、已非主流 |
| Json.NET | 現代 .NET 應用、Web API、高效能需求 | 第三方套件,但已成事實標準 |
根據專案限制與需求靈活選擇,避免踩序列化陷阱。