摘要:Json序列化與反序列化
這次嘗試使用 Json.NET 來處理Json物件的轉換
它是一個處理Json上頗為流行的第三方函式庫
目標是轉換一個關於球隊資料Json結構
{
Name: "TuRoMa Rabbit",
city: "TuRoMa",
Established: "1900-03-01",
League: "Namek Football League",
ChampionsCount: 39,
Rank: 2,
IsFefunct: false
}
對應的序列化物件模型定義大致上應與Json相符,
關於Json欄位的Type判斷可參考 官網定義 或 JSON DataTypes
一般來說如果沒有特別宣告,Json 的 key 與物件屬性名稱一樣即可自動對應
[JsonObject(Newtonsoft.Json.MemberSerialization.OptOut)]
internal class Team
{
public int ChampionsCount { get; set; }
public string CITY { get; set; }
public DateTime Established { get; set; }
public bool IsFefunct { get; set; }
[JsonProperty("League")]
public string LeagueName { get; set; }
[JsonIgnore]
public string Name { get; set; }
public int Rank { get; set; }
}
在Json.NET的用法來說要(反)序列化也只要一行就可完成轉換
// 反序列化
Team team = JsonConvert.DeserializeObject(jsonText);
// 序列化
string serializeData = JsonConvert.SerializeObject(team);
在屬性對應的策略上,可以選擇預設全部對應或者預設全部不對應
//預設每一個屬性都對應,如果類別上面無特別宣告也是採用此設定
[JsonObject(Newtonsoft.Json.MemberSerialization.OptOut)]
//此屬性不進行序列化與反序列化轉換
[JsonIgnore]
public string Name{get;set;}
//----------------------------------
//預設所有屬性皆不對應,僅特別設定過JsonPropertyAttribute的欄位才處理
[JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
//宣告此屬性需轉換
[JsonProperty]
public string League { get; set; }
//如果有命名不一致的情況必須特別宣告
[JsonProperty("League")
public string LeagueName { get; set; }
如果有仔細觀察上面的Json資料與Team物件,我刻意將Team.CITY 寫成大寫,雖然與Json的名稱一樣但大小寫不一致,在 Deserialize 過程中它依舊可以正確對應,代表它在處理過程中是 case-insentive.但必須注意如果是 Serialize 後的Json key就變成全大寫了,必須小心!關於解決這個問題的方法則可以採用JsonPropertyAttribute來進行強制轉換
陣列的轉換與子階層模型
現在Json的結構多了數筆球員資料
Members:
[
{
Name: "John",
Number: 99,
Position: "Quarterback"
},
{
Name: "Tim",
Number: 18,
Position: "Running back"
}
]
Members 這個欄位的類型是陣列 (Array),則物件對應時會變成 IEnumerable<>
如果您還沒建立球員的對應模型的話可以先用 JObject 或 JToken 代替
先建立球員的模型
[JsonObject(Newtonsoft.Json.MemberSerialization.OptOut)]
public class Member
{
public string Name { get; set; }
public int Number { get; set; }
public string Position { get; set; }
}
在隊伍的模型當中新增球員列表的屬性
public IEnumerable < Member > Members { get; set; }
心得
有一段時間在處理資料的時候都直接將 Json 解序列化成JObject,所以寫法常常就會在JObject、JToken上面著墨,但是這樣簡單的一個取值功能就會變得又臭又長,建議接收端接到Json資料時第一步就解成自己定義的物件,這樣才會讓程式碼簡潔許多,但還是需注意在欄位的轉換上如果有特殊需求的話可能要多注意一些,多觀察轉換前後是否有格式跑掉的情況