C# Newtonsoft.Json JsonSerializerSettings配置

Posted net-sky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# Newtonsoft.Json JsonSerializerSettings配置相关的知识,希望对你有一定的参考价值。

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     }
View Code
技术图片
 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));
View Code

输出结果:

{"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));
View Code

输出结果:

{"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; }
View Code

输出结果:{"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);
View Code

输出结果:{"BirthDay":"2011-01-01 00:00:00"}

同时指定时以特性(即方案1)为准

解决方案3:

object model = new object();

var jsonSettings = new JsonSerializerSettings();

jsonSettings.DateFormatHandling = DatFormatHandling.IsoDateFormat;

jsonSettings.Converters.Add(new Newtonsoft.Json.Converters.IsoDateTimeConverter () {DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"});

string content = JsonConvert.SerializeObject (model,Formatting.Indented,jsonSettings);

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);
View Code

过滤属性名为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;
View Code

指定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

以上是关于C# Newtonsoft.Json JsonSerializerSettings配置的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将字符串转换为 json 格式。 Newtonsoft.json 显示黄色标记

C# NEWTONSOFT.JSON读取json文件

使用 NewtonSoft Json 在 C# 中获取 JSON 的所有子项

Asp.net C# 使用Newtonsoft.Json 实现DataTable转Json格式数据

C# 无法访问 Newtonsoft.Json.Linq.JProperty 上的子值

C# Newtonsoft.Json JsonSerializerSettings 全局序列化设置