一:講故事
看完官方文件,閱讀了一些 Newtonsoft
原始碼,對它有了新的認識,先總結 六個超經典又實用的特性,同大家一起分享,廢話不多說,快來一起看看吧~~~
二:特性分析
1. 程式碼格式化
如果你直接使用 JsonConvert.SerializeObject
的話,預設情況下所有的json是擠壓在一塊的,特別不方便閱讀,如下所示:
static void Main(string[] args)
{
var reportModel = new ReportModel()
{
ProductName = "法式小眾設計感長裙氣質顯瘦純白色仙女連衣裙",
TotalPayment = 100,
TotalCustomerCount = 2,
TotalProductCount = 333
};
var json = JsonConvert.SerializeObject(reportModel);
System.Console.WriteLine(json);
}
}
public class ReportModel
{
public string ProductName { get; set; }
public int TotalCustomerCount { get; set; }
public decimal TotalPayment { get; set; }
public int TotalProductCount { get; set; }
}
那怎麼辦呢? JsonConvert中提供了一個 Formatting.Indented
用來格式化json,這樣在 debug 的過程中就非常友好,改造如下:
2. 踢掉沒有被賦值的欄位
如果你寫過給 App 提供資料的後端服務,我相信你對手機流量這個詞特別敏感,往往一個 Model 上有十幾個欄位,但需要傳給 App 可能就 三四個欄位,這就造成了巨大的流量浪費,如下圖:
static void Main(string[] args)
{
var reportModel = new ReportModel()
{
ProductName = "法式小眾設計感長裙氣質顯瘦純白色仙女連衣裙",
TotalPayment = 100
};
var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented);
System.Console.WriteLine(json);
}
從圖中可以看到,TotalCustomerCount
和 TotalProductCount
這兩個欄位就沒必要了,Netnewsoft 中提供了 DefaultValueHandling.Ignore
剔除預設值的列舉,太實用了,改造如下:
var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented,
new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
});
3. 相容其他語言的 駝峰,蛇形命名法
每一套程式語言都有各自偏好的命名法,比如 js 中都喜歡採用 駝峰命名法,在 mysql 中我見過最多的 蛇形命名法,而我們在 C# 中序列化的屬性一般都是大寫字母開頭,比如你看到的 特性二
中的欄位,那這裡就存在問題了,有沒有辦法相容一下,給 js 就用 駝峰,給 mysql 就用 蛇形,這樣顯得對別人友好一些,不是嘛???,接下來看看怎麼改造。
- 駝峰命名 CamelCasePropertyNamesContractResolver
var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
- 蛇形命名 SnakeCaseNamingStrategy
var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented,
new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver()
{
NamingStrategy = new SnakeCaseNamingStrategy()
}
});
4. 自定義屬性的名字
如果你和第三方系統進行過對接開發,通常都會遇到這個問題,就拿 OpenTaobao 來說,我的Model總不能按照它文件這樣定義吧,而且欄位名稱也不可能做到完全一致,如下圖:
所以這裡面必然要存在一個 Mapping 的過程,這就可以用 JsonProperty -> propertyName
幫你搞定,為了方便演示,我還是用 reportModel 吧。
static void Main(string[] args)
{
var json = "{'title':'法式小眾設計感長裙氣質顯瘦純白色仙女連衣裙','customercount':1000,'totalpayment':100.0,'productcount':10000}";
var reportModel = JsonConvert.DeserializeObject<ReportModel>(json);
}
public class ReportModel
{
[JsonProperty("title")] public string ProductName { get; set; }
[JsonProperty("customercount")] public int TotalCustomerCount { get; set; }
[JsonProperty("totalpayment")] public decimal TotalPayment { get; set; }
[JsonProperty("productcount")] public int TotalProductCount { get; set; }
}
5. 對欄位的 正向剔除 和 反向剔除
可能有些朋友對這兩個概念不是特別瞭解,這裡我僅顯示 Model 中的 ProductName 為例講解一下:
- 正向剔除: 預設所有都顯示,手工踢掉不顯示的,使用
MemberSerialization.OptOut
配合JsonIgnore
static void Main(string[] args)
{
var reportModel = new ReportModel()
{
ProductName = "法式小眾設計感長裙氣質顯瘦純白色仙女連衣裙",
TotalPayment = 100
};
var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented);
System.Console.WriteLine(json);
}
[JsonObject(MemberSerialization.OptOut)]
public class ReportModel
{
public string ProductName { get; set; }
[JsonIgnore] public int TotalCustomerCount { get; set; }
[JsonIgnore] public decimal TotalPayment { get; set; }
[JsonIgnore] public int TotalProductCount { get; set; }
}
- 反向剔除: 預設都不顯示,手工指定要顯示的,使用
MemberSerialization.OptIn
配合JsonProperty
[JsonObject(MemberSerialization.OptIn)]
public class ReportModel
{
[JsonProperty] public string ProductName { get; set; }
public int TotalCustomerCount { get; set; }
public decimal TotalPayment { get; set; }
public int TotalProductCount { get; set; }
}
6. 多個json 合併到 一個Model
這個特性當初打破了我對 Newtonsoft 的認知觀,不知道您呢? 通常我們都會認為 一個 json 對應一個 model,一個 model 對應一個 json,居然還可以多個 json 對應一個 model 的情況,這就有意思了,場景大家可以自己想一想哈,這裡使用 PopulateObject
方法就可以輕鬆幫你搞定,接下來看看怎麼寫這個程式碼:
static void Main(string[] args)
{
var json1 = "{'ProductName':'法式小眾設計感長裙氣質顯瘦純白色仙女連衣裙'}";
var json2 = "{'TotalCustomerCount':1000,'TotalPayment':100.0,'TotalProductCount':10000}";
var reportModel = new ReportModel();
JsonConvert.PopulateObject(json1, reportModel);
JsonConvert.PopulateObject(json2, reportModel);
}
是不是有點意思???
三:總結
為了怕影響閱讀體驗,這一篇就先總結六個供大家欣賞,Newtonsoft 這玩意確實非常強大,太多的東西需要去挖掘,希望本篇對你有幫助,謝謝。