C# Newtonsoft.Json JsonSerializerSettings配置序列化操作
JsonSerializerSettings常用配置整理
1.忽略某些屬性
2.預設值的處理
3.空值的處理
4.支援非公共成員
5.日期處理(DateFormatHandling)
6.自定義序列化的欄位名稱
7.動態決定屬性是否序列化
8.列舉值的自定義格式化問題
9.自定義型別轉換
10.全域性序列化設定
11.指定序列化時Key的處理方式:駝峰樣式,預設樣式(ContractResolver)
12.序列化迴圈 引用及處理層數
特別 說明:Newtonsoft.Json不依賴.Net Framework,是基於 .Net Standard封裝的,僅支援.Net Framework也支援.Net Core
一 、忽略某些屬性
類似本問開頭介紹的介面優化,實體中有些屬性不需要序列化返回,可以使用該特性。首先介紹Json.Net序列化的模式:OptOut 和 OptIn
OptOut | 預設值,類中所有公有成員會被序列化,如果不想被序列化,可以用特性JsonIgnore |
OptIn | 預設情況下,所有的成員不會被序列化,類中的成員只有標有特性JsonProperty的才會被序列化,當類的成員很多,但客戶端僅僅需要一部分資料時,很有用 |
不指定的情況下,類都可以序列化,所有的公共屬性都會處理。
忽略指定屬性例項:
[JsonObject(MemberSerialization.OptIn)] public class Person { public int Age { get; set; } [JsonProperty] public string Name { get; set; } public string Sex { get; set; } public bool IsMarry { get; set; } public DateTime Birthday { get; set; } }
二、預設值處理
序列化時想忽略預設值屬性可以通過JsonSerializerSettings.DefaultValueHandling來確定,該值為列舉值
DefaultValueHandling.Ignore
|
序列化和反序列化時,忽略預設值 |
DefaultValueHandling.Include
|
序列化和反序列化時,包含預設值 |
不指定的情況下,序列化時包含 預設值。
三、空值處理
序列化時需要忽略值為NULL的屬性,可以通過JsonSerializerSettings.NullValueHandling來確定,另外通過JsonSerializerSettings設定屬性是對序列化過程中所有屬性生效的,想單獨對某一個屬性生效可以使用JsonProperty,下面將分別展示兩個方式
四 、支援 非公共成員
序列化時預設都是處理公共成員,如果需要處理非公共成員,就要在該成員上加特性"JsonProperty"
[JsonProperty] private int Height { get; set; }
五、日期格式處理
對於Dateime型別日期的格式化就比較麻煩了,系統自帶的會格式化成iso日期標準,但是實際使用過程中大多數使用的可能是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss兩種格式的日期,解決辦法是可以將DateTime型別改成string型別自己格式化好,然後在序列化。如果不想修改程式碼,可以採用下面方案實現。
Json.Net提供了IsoDateTimeConverter日期轉換這個類,可以通過JsnConverter實現相應的日期轉換
[JsonConverter(typeof(IsoDateTimeConverter))] public DateTime Birthday { get; set; }處理方式1.JsonSerializerSettings.DateFormatHandling 指定時間處理格式
處理方式2.DateTimeConverterBase 擴充套件重寫時間處理
示例如下:
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace System
{
public class LongDateTimeConvert : IsoDateTimeConverter
{
public LongDateTimeConvert() : base()
{
base.DateTimeFormat = "yyyy/MM/dd HH:mm";
}
}
}
使用:
[Newtonsoft.Json.JsonConverter(typeof(LongDateTimeConvert))]
public DateTime CreateTime { get; set; }
六、自定義序列化的 欄位名稱
實體中定義的屬性名可能不是自己想要的名稱,但是又不能更改實體定義,這個時候可以自定義序列化欄位名稱。
[JsonProperty(PropertyName = "CName")] public string Name { get; set; }七、動態決定屬性是否序列化
承預設的DefaultContractResolver類,傳入需要輸出的屬性,擴充套件操作,指定JsonSerializerSettings.ContractResolver的例項
八、列舉值的 自定義格式化處理
預設列舉輸出的是列舉的 值
public enum NotifyType
{
/// <summary>
/// Emil傳送
/// </summary>
Mail=0,
/// <summary>
/// 簡訊傳送
/// </summary>
SMS=1
}
public class TestEnmu
{
/// <summary>
/// 訊息傳送型別
/// </summary>
public NotifyType Type { get; set; }
}
JsonConvert.SerializeObject(new TestEnmu());
輸出結果:
現在改造一下,輸出"Type":"Mail" public class TestEnmu
{
/// <summary>
/// 訊息傳送型別
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public NotifyType Type { get; set; }
}
其它的都不變,在Type屬性上加上了JsonConverter(typeof(StringEnumConverter))表示將列舉值轉換成對應的字串,而StringEnumConverter是Newtonsoft.Json內建的轉換型別,最終輸出結果
九、自定義 型別轉換。
需要擴充套件類JsonConverter類 。
十、全域性序列化設定
文章開頭提出了Null值欄位怎麼不返回的問題,相應的在高階用法也給出了相應的解決方案使用jsetting.NullValueHandling = NullValueHandling.Ignore; 來設定不返回空值。這樣有個麻煩的地方,每個不想返回空值的序列化都需設定一下。
Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
{
//日期型別預設格式化處理
setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//空值處理
setting.NullValueHandling = NullValueHandling.Ignore;
//高階用法九中的Bool型別轉換 設定
setting.Converters.Add(new BoolConvert("是,否"));
return setting;
});
十一、序列化時 指定Key的處理方式,為駝峰式
CamelCasePropertyNamesContractResolver
//設定序列化時key為駝峰樣式
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.Formatting = Formatting.Indented;
string str = JsonConvert.SerializeObject(menus, settings);
Console.WriteLine(str);
輸出 字串格式化處理指定如下,預設沒有換行處理。
//Formatting.Indented 格式化json字串資料,鋸齒狀的
string str = JsonConvert.SerializeObject(menus,Formatting.Indented);
十二、對於Newtonsoft.Json預設 已經處理過迴圈引用,
也就是對於關聯表的 物件或列表都不會序列化出來。
//設定迴圈引用,及引用型別序列化的層數。
//注:目前在 EF core中目前不支援延遲載入,無所謂迴圈引用了
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Formatting = Formatting.Indented;
settings.MaxDepth = 10; //設定序列化的最大層數
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;//指定如何處理迴圈引用,None--不序列化,Error-丟擲異常,Serialize--仍要序列化
更多: