JsonSerializerSettings常用配置整理
1.忽略某些屬性
MemberSerialization.OptIn
默認情況下,所有的成員不會被序列化,類中的成員只有標有特性JsonProperty的才會被序列化,當類的成員很多,但客戶端僅僅需要一部分數據時,很有用

1 [JsonObject(MemberSerialization.OptIn)] 2 public class TestClass 3 { 4 public int A { get; set; } 5 public long B { get; set; } 6 public string C { get; set; } 7 [JsonProperty] 8 public DateTime D { get; set; } 9 public TestEnum E { get; set; } 10 [JsonIgnore] 11 public TestClass F { get; set; } 12 public List<TestClass> G { get; set; } 13 public bool H { get; set; } 14 } 15 public enum TestEnum 16 { 17 TestEnum0 = 0, 18 TestEnum1 = 1, 19 TestEnum2 = 2, 20 TestEnum3 = 3, 21 } 22 [JsonObject(MemberSerialization.OptIn)] 23 public class Person 24 { 25 [JsonIgnore] 26 public string Name { get; set; } 27 [JsonProperty] 28 public int Age { get; set; } 29 public DateTime BirthDay { get; set; } 30 }

1 Console.WriteLine(JsonConvert.SerializeObject(new Person { Name = "test", Age = 18, BirthDay = new DateTime(2011, 1, 1) })); 2 TestClass testClass = new TestClass 3 { 4 A = 1, 5 B = 2, 6 C = "C", 7 D = DateTime.Now, 8 E = TestEnum.TestEnum1, 9 F = new TestClass 10 { 11 A = 11, 12 B = 22, 13 C = "Cc", 14 D = DateTime.Now, 15 E = TestEnum.TestEnum2, 16 F = new TestClass() 17 }, 18 G = new List<TestClass> 19 { 20 new TestClass 21 { 22 A=111, 23 B=222, 24 C="CCC", 25 E=TestEnum.TestEnum1, 26 F=new TestClass() 27 } 28 } 29 }; 30 Console.WriteLine(JsonConvert.SerializeObject(testClass));
輸出結果:
{"Age":18}
{"D":"2019-11-26T10:37:33.7655514+08:00"}
MemberSerialization.OptOut
默認類中所有公有成員會被序列化,如果不想被序列化,可以用特性JsonIgnore
將上面的代碼OptIn改為OptOut輸出結果:
{"Age":18,"BirthDay":"2011-01-01T00:00:00"}
{"A":1,"B":2,"C":"C","D":"2019-11-26T15:49:37.9507028+08:00","E":1,"G":[{"A":111,"B":222,"C":"CCC","D":"0001-01-01T00:00:00","E":1,"G":null,"H":false}],"H":false}
2.默認值的處理
DefaultValueHandling.Ignore 序列化和反序列化時,忽略默認值

1 TestClass testClass = new TestClass 2 { 3 A = 1, 4 B = 2, 5 C = "C", 6 D = DateTime.Now, 7 E = TestEnum.TestEnum1, 8 F = new TestClass 9 { 10 A = 11, 11 B = 22, 12 C = "Cc", 13 D = DateTime.Now, 14 E = TestEnum.TestEnum2, 15 F = new TestClass() 16 }, 17 G = new List<TestClass> 18 { 19 new TestClass 20 { 21 A=111, 22 B=222, 23 C="CCC", 24 E=TestEnum.TestEnum1, 25 F=new TestClass() 26 } 27 } 28 }; 29 JsonSerializerSettings settings = new JsonSerializerSettings(); 30 settings.DefaultValueHandling = DefaultValueHandling.Ignore; 31 Console.WriteLine(JsonConvert.SerializeObject(testClass,settings));
輸出結果:
{"A":1,"B":2,"C":"C","D":"2019-11-26T15:56:21.7204132+08:00","E":1,"G":[{"A":111,"B":222,"C":"CCC","E":1}]}
DefaultValueHandling.Include 序列化和反序列化時,包含默認值
將JsonSerializerSettings.DefaultValueHandling屬性設為DefaultValueHandling.Include輸出結果:
{"A":1,"B":2,"C":"C","D":"2019-11-26T16:21:48.5429746+08:00","E":1,"G":[{"A":111,"B":222,"C":"CCC","D":"0001-01-01T00:00:00","E":1,"G":null,"H":false}],"H":false}
DefaultValueHandling.Populate 在反序列化時,具有默認值但沒有JSON的成員將被設置為其默認值。
DefaultValueHandling.IgnoreAndPopulate 在序列化對象時忽略成員值與成員默認值相同的成員,在反序列化時將成員設置為其默認值
不指定的情況下,序列化時 默認 包含-DefaultValueHandling.Include
3.空值的處理
設置JsonSerializerSettings.NullValueHandling屬性
對序列化過程中所有屬性生效的,想單獨對某一個屬性生效可以使用JsonProperty
值為NullValueHandling.Ignore時,輸出結果為:
{"A":1,"B":2,"C":"C","D":"2019-11-26T16:34:21.3205145+08:00","E":1,"G":[{"A":111,"B":222,"C":"CCC","D":"0001-01-01T00:00:00","E":1,"H":false}],"H":false}
值為NullValueHandling.Include時,輸出結果為:
{"A":1,"B":2,"C":"C","D":"2019-11-26T16:34:21.3205145+08:00","E":1,"G":[{"A":111,"B":222,"C":"CCC","D":"0001-01-01T00:00:00","E":1,"G":null,"H":false}],"H":false}
4.支持非公共成員
序列化時默認都是處理公共成員,如果需要處理非公共成員,就要在該成員上加特性JsonProperty
5.日期處理(DateFormatHandling)
對於Dateime類型日期的格式化,系統自帶的會格式化成iso日期標准{"BirthDay":"2011-01-01T00:00:00"}
解決方案1:添加特性,指定轉換格式

1 public class LongDateTimeConvert: Newtonsoft.Json.Converters.IsoDateTimeConverter 2 { 3 public LongDateTimeConvert() : base() 4 { 5 base.DateTimeFormat = "yyyy-MM-dd"; 6 } 7 } 8 //[JsonConverter(typeof(LongDateTimeConvert))] 9 public DateTime BirthDay { get; set; }
輸出結果:{"BirthDay":"2011-01-01"}
解決方案2:指定JsonSerializerSettings.DateFormatString的值

1 JsonSerializerSettings settings = new JsonSerializerSettings(); 2 settings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 3 var str = JsonConvert.SerializeObject(new Person { Name = "test", Age = 18, BirthDay = new DateTime(2011, 1, 1) }, settings); 4 Console.WriteLine(str);
輸出結果:{"BirthDay":"2011-01-01 00:00:00"}
同時指定時以特性(即方案1)為准
6.自定義序列化的字段名稱
實體中定義的屬性名可能不是自己想要的名稱,但是又不能更改實體定義,這個時候可以自定義序列化字段名稱
[JsonProperty(PropertyName = "age")]
public int Age { get; set; }
輸出結果:{"age":18}
7.動態決定屬性是否序列化
指定JsonSerializerSettings.ContractResolver的實例,繼承DefaultContractResolver類,重寫方法

1 public class JsonContractResolver : DefaultContractResolver 2 { 3 protected IEnumerable<string> _excludedProperties; 4 public JsonContractResolver(IEnumerable<string> excludedProperties) 5 { 6 this._excludedProperties = excludedProperties; 7 } 8 protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 9 { 10 return base.CreateProperties(type, memberSerialization).Where(a=>!this._excludedProperties.Contains(a.PropertyName)).ToList(); 11 } 12 } 13 JsonSerializerSettings settings = new JsonSerializerSettings(); 14 settings.ContractResolver =new JsonContractResolver(new[] { "Sign" }); 15 settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; 16 settings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 17 var str = JsonConvert.SerializeObject(new Person { Name = "test", Age = 18, BirthDay = new DateTime(2011, 1, 1) }, settings); 18 Console.WriteLine(str);
過濾屬性名為Sign的字段,輸出結果:{"age":18,"BirthDay":"2011-01-01T00:00:00"}
8.枚舉值的自定義格式化問題
默認枚舉輸出的是枚舉的 值 {"E":1}
在屬性上加上JsonConverter(typeof(StringEnumConverter))表示將枚舉值轉換成對應的字符串,StringEnumConverter是Newtonsoft.Json內置的轉換類型
輸出結果:{"E":"TestEnum1"}
9.自定義類型轉換
需要擴展類JsonConverter類
10.全局序列化設置

1 JsonSerializerSettings settings = new JsonSerializerSettings(); 2 settings.ContractResolver =new JsonContractResolver(new[] { "Sign" }); 3 settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; 4 settings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 5 JsonConvert.DefaultSettings = () => settings;
指定JsonConvert.DefaultSettings
11.指定序列化時Key的處理方式:駝峰樣式,默認樣式(ContractResolver)
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
var str = JsonConvert.SerializeObject(new Person { Name = "test", Age = 18, BirthDay = new DateTime(2011, 1, 1) },Formatting.Indented);
Formatting.Indented 格式化json字符串數據,鋸齒狀的
輸出結果:
{
"sign": false,
"age": 18,
"birthDay": "2011-01-01T00:00:00"
}
12.序列化循環 引用及處理層數
對於關聯表的 對象或列表都不會序列化出來
//設置循環引用,及引用類型序列化的層數。
//注:目前在 EF core中目前不支持延遲加載,無所謂循環引用了
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Formatting = Formatting.Indented;
settings.MaxDepth = 10; //設置序列化的最大層數
settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;//指定如何處理循環引用,None--不序列化,Error-拋出異常,Serialize--仍要序列化
本文參考文檔:
https://blog.csdn.net/u011127019/article/details/72801033
Newtonsoft.Json 官方文檔:https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonSerializerSettings.htm