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

官网地址:http://www.newtonsoft.com/json,Nuget 地址:https://www.nuget.org/packages/Newtonsoft.Json


一 、忽略某些属性

类似本问开头介绍的接口优化,实体中有些属性不需要序列化返回,可以使用该特性。首先介绍Json.Net序列化的模式:OptOut 和 OptIn

OptOut      默认值,类中所有公有成员会被序列化,如果不想被序列化,可以用特性JsonIgnore
OptIn默认情况下,所有的成员不会被序列化,类中的成员只有标有特性JsonProperty的才会被序列化,当类的成员很多,但客户端仅仅需要一部分数据时,很有用






不指定的情况下,类都可以序列化,所有的公共属性都会处理。

忽略指定属性实例:


[csharp] view plain copy
  1. [JsonObject(MemberSerialization.OptIn)]  

  2.    public class Person  

  3.    {  

  4.        public int Age { getset; }  

  5.   

  6.        [JsonProperty]  

  7.        public string Name { getset; }  

  8.   

  9.        public string Sex { getset; }  

  10.   

  11.        public bool IsMarry { getset; }  

  12.   

  13.        public DateTime Birthday { getset; }  

  14.    }  


二、默认值处理


   序列化时想忽略默认值属性可以通过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 扩展重写时间处理

示例如下:


[csharp] view plain copy
  1. using Newtonsoft.Json;  

  2. using Newtonsoft.Json.Converters;  

  3. namespace System  

  4. {  

  5.     public class LongDateTimeConvert : IsoDateTimeConverter  

  6.     {  

  7.         public LongDateTimeConvert() : base()  

  8.         {  

  9.             base.DateTimeFormat = "yyyy/MM/dd HH:mm";  

  10.         }  

  11.     }  

  12. }  

使用:


[csharp] view plain copy
  1. [Newtonsoft.Json.JsonConverter(typeof(LongDateTimeConvert))]  

  2. public DateTime CreateTime { getset; }  





六、自定义序列化的 字段名称


 实体中定义的属性名可能不是自己想要的名称,但是又不能更改实体定义,这个时候可以自定义序列化字段名称。

     [JsonProperty(PropertyName = "CName")]     public string Name { get; set; }

七、动态决定属性是否序列化

承默认的DefaultContractResolver类,传入需要输出的属性,扩展操作,指定JsonSerializerSettings.ContractResolver的实例 

八、枚举值的 自定义格式化处理

默认枚举输出的是枚举的 值


[csharp] view plain copy
  1. <span style="font-family:black Verdana, Arial, Helvetica, sans-serif;"><span style="font-size: 14px;">   </span></span> public enum NotifyType  

  2.     {  

  3.         /// <summary>  

  4.         /// Emil发送  

  5.         /// </summary>  

  6.         Mail=0,  

  7.   

  8.         /// <summary>  

  9.         /// 短信发送  

  10.         /// </summary>  

  11.         SMS=1  

  12.     }  

  13.   

  14.     public class TestEnmu  

  15.     {  

  16.         /// <summary>  

  17.         /// 消息发送类型  

  18.         /// </summary>  

  19.         public NotifyType Type { getset; }  

  20.     }  

  21.     JsonConvert.SerializeObject(new TestEnmu());  

输出结果:  现在改造一下,输出"Type":"Mail"

[csharp] view plain copy
  1. public class TestEnmu  

  2.  {  

  3.      /// <summary>  

  4.      /// 消息发送类型  

  5.      /// </summary>  

  6.      [JsonConverter(typeof(StringEnumConverter))]  

  7.      public NotifyType Type { getset; }  

  8.  }  


其它的都不变,在Type属性上加上了JsonConverter(typeof(StringEnumConverter))表示将枚举值转换成对应的字符串,而StringEnumConverter是Newtonsoft.Json内置的转换类型,最终输出结果

九、自定义 类型转换。

需要扩展类JsonConverter类 。

十、全局序列化设置

文章开头提出了Null值字段怎么不返回的问题,相应的在高级用法也给出了相应的解决方案使用jsetting.NullValueHandling = NullValueHandling.Ignore; 来设置不返回空值。这样有个麻烦的地方,每个不想返回空值的序列化都需设置一下。

[csharp] view plain copy
  1. Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();  

  2.   JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>  

  3.   {  

  4.    //日期类型默认格式化处理  

  5.     setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;  

  6.      setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";  

  7.   

  8.    //空值处理  

  9.      setting.NullValueHandling = NullValueHandling.Ignore;  

  10.   

  11.      //高级用法九中的Bool类型转换 设置  

  12.      setting.Converters.Add(new BoolConvert("是,否"));  

  13.   

  14.      return setting;  

  15.   });  

十一、序列化时 指定Key的处理方式,为驼峰式


CamelCasePropertyNamesContractResolver

[csharp] view plain copy
  1. //设置序列化时key为驼峰样式  

  2. JsonSerializerSettings settings = new JsonSerializerSettings();  

  3. settings.ContractResolver = new CamelCasePropertyNamesContractResolver();  

  4. settings.Formatting = Formatting.Indented;  

  5.   

  6. string str = JsonConvert.SerializeObject(menus, settings);  

  7. Console.WriteLine(str);  


输出 字符串格式化处理指定如下,默认没有换行处理。

[csharp] view plain copy
  1. //Formatting.Indented 格式化json字符串数据,锯齿状的  

  2. string str = JsonConvert.SerializeObject(menus,Formatting.Indented);  


十二、对于Newtonsoft.Json默认 已经处理过循环引用,

也就是对于关联表的 对象或列表都不会序列化出来。

[csharp] view plain copy
  1. //设置循环引用,及引用类型序列化的层数。  

  2. //注:目前在 EF core中目前不支持延迟加载,无所谓循环引用了  

  3. JsonSerializerSettings settings = new JsonSerializerSettings();  

  4. settings.Formatting = Formatting.Indented;  

  5. settings.MaxDepth = 10; //设置序列化的最大层数  

  6. settings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;//指定如何处理循环引用,None--不序列化,Error-抛出异常,Serialize--仍要序列化