Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称 Newtonsoft.Json介绍 基本用法 高级用法 总结

 手机端应用讲究速度快,体验好。刚好手头上的一个项目服务端接口有性能问题,需要进行优化。在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数据,经过分析一个简单的列表接口每一行数据返回了16个字段,但是手机APP端只用到了其中7个字段,剩余9个字段的数据全部都是多余的,如果接口返回数据为40K大小,也就是说大约20K的数据为无效数据,3G网络下20K下载差不多需要1s,不返回无效数据至少可以节约1s的时间,大大提高用户体验。本篇将为大家介绍Newtonsoft.Json的一些高级用法,可以修改很少的代码解决上述问题。

阅读目录

  在做开发的时候,很多数据交换都是以json格式传输的。而使用Json的时候,我们很多时候会涉及到几个序列化对象的使用:DataContractJsonSerializer,JavaScriptSerializer  Json.NET即Newtonsoft.Json。大多数人都会选择性能以及通用性较好Json.NET,这个不是微软的类库,但是一个开源的世界级的Json操作类库,从下面的性能对比就可以看到它的其中之一的性能优点。

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

齐全的API介绍,使用方式简单

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

基本用法

  Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity的。下面分别举例说明序列化和反序列化。

DataTable:

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结
            //序列化DataTable
            DataTable dt = new DataTable();
            dt.Columns.Add("Age", Type.GetType("System.Int32"));
            dt.Columns.Add("Name", Type.GetType("System.String"));
            dt.Columns.Add("Sex", Type.GetType("System.String"));
            dt.Columns.Add("IsMarry", Type.GetType("System.Boolean"));
            for (int i = 0; i < 4; i++)
            {
                DataRow dr = dt.NewRow();
                dr["Age"] = i + 1;
                dr["Name"] = "Name" + i;
                dr["Sex"] = i % 2 == 0 ? "男" : "女";
                dr["IsMarry"] = i % 2 > 0 ? true : false;
                dt.Rows.Add(dr);
            }
            Console.WriteLine(JsonConvert.SerializeObject(dt));
Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

利用上面字符串进行反序列化

 string json = JsonConvert.SerializeObject(dt);
 dt=JsonConvert.DeserializeObject<DataTable>(json);
 foreach (DataRow dr in dt.Rows)
 {
   Console.WriteLine("{0}	{1}	{2}	{3}	", dr[0], dr[1], dr[2], dr[3]);
 }

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

Entity序列化和DataTable一样,就不过多介绍了。

高级用法

    1.忽略某些属性

    2.默认值的处理

    3.空值的处理

    4.支持非公共成员

    5.日期处理

    6.自定义序列化的字段名称

 一.忽略某些属性

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

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

 仅需要姓名属性

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结
    [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; }
    }
Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

  不需要是否结婚属性

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结
    [JsonObject(MemberSerialization.OptOut)]
    public class Person
    {
        public int Age { get; set; }

        public string Name { get; set; }

        public string Sex { get; set; }

        [JsonIgnore]
        public bool IsMarry { get; set; }

        public DateTime Birthday { get; set; }
    }
Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

  通过上面的例子可以看到,要实现不返回某些属性的需求很简单。1.在实体类上加上[JsonObject(MemberSerialization.OptOut)] 2.在不需要返回的属性上加上 [JsonIgnore]说明。

二.默认值处理

    序列化时想忽略默认值属性可以通过JsonSerializerSettings.DefaultValueHandling来确定,该值为枚举值

DefaultValueHandling.Ignore
序列化和反序列化时,忽略默认值
DefaultValueHandling.Include
序列化和反序列化时,包含默认值
 [DefaultValue(10)]
 public int Age { get; set; }
 Person p = new Person { Age = 10, Name = "张三丰", Sex = "男", IsMarry = false, Birthday = new DateTime(1991, 1, 2) };
 JsonSerializerSettings jsetting=new JsonSerializerSettings();
 jsetting.DefaultValueHandling=DefaultValueHandling.Ignore;
 Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

最终结果如下:

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

三.空值的处理

  序列化时需要忽略值为NULL的属性,可以通过JsonSerializerSettings.NullValueHandling来确定,另外通过JsonSerializerSettings设置属性是对序列化过程中所有属性生效的,想单独对某一个属性生效可以使用JsonProperty,下面将分别展示两个方式

  1.JsonSerializerSettings

 Person p = new Person { room=null,Age = 10, Name = "张三丰", Sex = "男", IsMarry = false, Birthday = new DateTime(1991, 1, 2) };
 JsonSerializerSettings jsetting=new JsonSerializerSettings();
 jsetting.NullValueHandling = NullValueHandling.Ignore;
 Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

   Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

   2.JsonProperty

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

通过JsonProperty属性设置的方法,可以实现某一属性特别处理的需求,如默认值处理,空值处理,自定义属性名处理,格式化处理。上面空值处理实现

 [JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
 public Room room { get; set; }

四.支持非公共成员

  序列化时默认都是处理公共成员,如果需要处理非公共成员,就要在该成员上加特性"JsonProperty"

 [JsonProperty]
 private int Height { get; set; }

五.日期处理

  对于Dateime类型日期的格式化就比较麻烦了,系统自带的会格式化成iso日期标准Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结,但是实际使用过程中大多数使用的可能是yyyy-MM-dd 或者yyyy-MM-dd HH:mm:ss两种格式的日期,解决办法是可以将DateTime类型改成string类型自己格式化好,然后在序列化。如果不想修改代码,可以采用下面方案实现。

      Json.Net提供了IsoDateTimeConverter日期转换这个类,可以通过JsnConverter实现相应的日期转换

    [JsonConverter(typeof(IsoDateTimeConverter))]
    public DateTime Birthday { get; set; }

  但是IsoDateTimeConverter日期格式不是我们想要的,我们可以继承该类实现自己的日期

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结
    public class ChinaDateTimeConverter : DateTimeConverterBase
    {
        private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" };

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            dtConverter.WriteJson(writer, value, serializer);
        }
    }
Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

    自己实现了一个yyyy-MM-dd格式化转换类,可以看到只是初始化IsoDateTimeConverter时给的日期格式为yyyy-MM-dd即可,下面看下效果

[JsonConverter(typeof(ChinaDateTimeConverter))]
public DateTime Birthday { get; set; }

Newtonsoft.Json高级用法    1.忽略某些属性      2.默认值的处理      3.空值的处理      4.支持非公共成员      5.日期处理      6.自定义序列化的字段名称
Newtonsoft.Json介绍
基本用法
高级用法
总结

   可以根据自己需求实现不同的转换类

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

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

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

总结

  Newtonsoft.Json序列化库替我们想了很多特性,也实现了很多特性,除了上面介绍的六种高级用法外,还有其它的特殊用法,可以去官网进行学习。当然这里我目前最喜欢的特性就是那个忽略部分属性序列化的功能,很小的代码改动实现了接口的优化,提升了用户体验。