Json.Net系列教程 3.Json.Net序列化和反序列化设置

简介: 原文 Json.Net系列教程 3.Json.Net序列化和反序列化设置 上节补充 首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.

原文 Json.Net系列教程 3.Json.Net序列化和反序列化设置

上节补充

首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我举例说明DataTable的序列化和反序列化.
创建一个DataTable对象,如下:

复制代码
            DataTable dt = new DataTable();
            DataColumn dcName = new DataColumn("Name");
            DataColumn dcAge = new DataColumn("Age");
            DataColumn dcCity = new DataColumn("City");

            dt.Columns.Add(dcName);
            dt.Columns.Add(dcAge);
            dt.Columns.Add(dcCity);
            for (int i = 0; i < 10; i++)
            {
                DataRow dr = dt.NewRow();
                dr[0] = "Name" + i;
                dr[1] = "Age" + i;
                dr[2] = "City" + i;
                dt.Rows.Add(dr);
            }
复制代码

序列化:

            string json = JsonConvert.SerializeObject(dt);
            Console.WriteLine(json);

结果:

利用上面得到的序列化字符串反序列化:

复制代码
            DataTable dt1 = JsonConvert.DeserializeObject<DataTable>(json);
            for (int i = 0; i < dt1.Rows.Count; i++)
            {
                DataRow dr = dt1.Rows[i];
                Console.WriteLine("{0}\t{1}\t{2}\t", dr[0], dr[1], dr[2]);
            }
复制代码

结果:

本节内容

预备知识:

要想实现对Json.Net序列化和反序列化的控制,就要用到类JsonSerializerSettings,用法很简单实例化一个对象,并把它赋值给JsonConvert的参数即可.

            var jSetting = new JsonSerializerSettings();
            string json = JsonConvert.SerializeObject(obj,jSetting);

开始之前,我还是先创建一员工类:

复制代码
    public class Staff
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Gender { get; set; }
        public string DepartmentName { get; set; }
        public Staff Leader { get; set; }
    }
复制代码
一.空值的处理

这里的空值指的是引用类型为NULL时,Json.Net如何处理.通过设置jSetting.NullValueHandling的值来确定,该值为枚举类型.

NullValueHandling.Ignore
忽略为NULL的值
NullValueHandling.Include
默认值,包括为NULL的值

 

 

 

 

实例:

复制代码
            Staff jack = new Staff { Name = "Jack", Age = 31, Gender = "Male", DepartmentName = "Personnel Department", Leader = null };
            var jSetting = new JsonSerializerSettings();
            jSetting.NullValueHandling = NullValueHandling.Ignore;
            string json = JsonConvert.SerializeObject(jack,jSetting);
            Console.WriteLine(json);
复制代码

结果:

2.默认值的处理

 一般是对于值类型的处理,通过设置jSetting.DefaultValueHandling的值来确定,该值为枚举类型.

DefaultValueHandling.Ignore
序列化和反序列化时,忽略默认值
DefaultValueHandling.Include
序列化和反序列化时,包含默认值

 

 

 

 

给成员设置默任值,用到"DefaultValue(value)"特性,当然别忘了引入命名空间"System.ComponentModel",假设员工的年龄默认值为30

        [DefaultValue(30)]
        public int Age { get; set; }

序列化时我想忽略为默认值的成员

复制代码
            Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male", DepartmentName = "Personnel Department", Leader = null };
            var jSetting = new JsonSerializerSettings();
            jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
            string json = JsonConvert.SerializeObject(jack,jSetting);
            Console.WriteLine(json);
复制代码

结果:

3.忽略某些属性

首先介绍Json.Net序列化的模式:OptOut 和 OptIn.

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

 

 

假如客户仅仅需要员工的姓名,此时

复制代码
    [JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
    public class Staff
    {
        [JsonProperty]
        public string Name { get; set; }
        public int Age { get; set; }
        public string Gender { get; set; }
        public string DepartmentName { get; set; }
        public Staff Leader { get; set; }
    }
复制代码

序列化:

            Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male", DepartmentName = "Personnel Department", Leader = null };
            string json = JsonConvert.SerializeObject(jack);

结果:

如果客户不想要员工的领导信息

复制代码
    public class Staff
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Gender { get; set; }
        public string DepartmentName { get; set; }
        [JsonIgnore]
        public Staff Leader { get; set; }
    }
复制代码

序列化:

            Staff tom = new Staff { Name = "Tome", Age = 42, Gender = "Male", DepartmentName = "Personnel Department"};
            Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male", DepartmentName = "Personnel Department", Leader = tom };
            string json = JsonConvert.SerializeObject(jack);
            Console.WriteLine(json);

结果:

4.支持非公共成员

Json.Net序列化对象时,默认情况下仅仅序列化公有成员,如果想要非公有成员也被序列化,就要在该成员上加特性"JsonProperty"

5.日期处理

  JsonConverters会在序列化和反序列化时被用到。JsonConverters允许手动对Json的控制。当Json的结构很复杂 和你想改变一个类型怎么样被序列化时,这是非常有用的。当一个JsonConverters被添加到JsonSerializer时,它会检查每一要被序 列化和反序列化的值,并返回CanConvert,如果为True,则JsonConverter读和写这个值;需要注意的是,虽然 JsonConverter能够使你可以完全的控制Json的值,但是很多的Json.Net序列化的特性被限制,像是类型名称和引用处理。所有的 JsonConvert都在命名空间 "Newtonsoft.Json.Converters"

5.1 IsoDateTimeConverter  JavaScriptDateTimeConverter

这是Json.Net中自带的两个处理日期的类,默认是IsoDateTimeConverter ,它的格式是"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK".另一个是JavaScriptTimeConverter,它的格式是 "new Date(ticks)",其实返回的是一个JavaScript的Date对象.
有两种方式来应用JsonConverter,改变Json序列化和反序列化的行为.

5.1.1如果你要序列化的日期格式是统一的,可以考虑如下方式

假设我们为员工添加两个日期类型的成员,出生日期和入职日期

复制代码
    public class Staff
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Gender { get; set; }
        public string DepartmentName { get; set; }
        public Staff Leader { get; set; }
        public DateTime BirthDate { get; set; }
        public DateTime EmploymentDate { get; set; }
    }
复制代码

我们的客户要求日期类型的成员返回javascript的日期对象

            Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male",
                DepartmentName = "Personnel Department", BirthDate = new DateTime(1982,2,12), EmploymentDate = new DateTime(2010,12,12) };
            string json = JsonConvert.SerializeObject(jack,new JavaScriptDateTimeConverter());
            Console.WriteLine(json);

结果:

 

5.1.2如果想要不同的日期类型成员序列化后,以不同的形式显示.

现在我们的客户要求出生日期以"ISO"标准日期格式返回,入职日期以Javascript的Date对象格式返回,修改我们的员工类

复制代码
    public class Staff
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Gender { get; set; }
        public string DepartmentName { get; set; }
        public Staff Leader { get; set; }
        [JsonConverter(typeof(IsoDateTimeConverter))]
        public DateTime BirthDate { get; set; }
        [JsonConverter(typeof(JavaScriptDateTimeConverter))]
        public DateTime EmploymentDate { get; set; }
    }
复制代码

是的,通过特性"JsonConverter"来实现差异化的
序列化:

            Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male",
                DepartmentName = "Personnel Department", BirthDate = new DateTime(1982,2,12), EmploymentDate = new DateTime(2010,12,12) };
            string json = JsonConvert.SerializeObject(jack);
            Console.WriteLine(json);

结果:

5.2自定义日期格式

客户现在提出要求,希望得到的日期格式是符合中国人习惯的格式.要求返回的格式是"2012年4月20日".挑战来了,没有挑战就没有进步,我喜欢挑战.光说是没有用的!先分析一下怎么解决这个问题.我考虑了两种思路.
  思路一:
研究了一下上面两个日期处理类,发现他们都是继承了基类"DateTimeConverterBase",所以我们可以参考"IsoDatetimeConverter"的实现方式,自己新建一个处理日期格式的转换器类.这种方式的缺点是可能要花大量的时间去研究,比较费时费力.优点就是可以对日期格式随心所欲的控制.
  思路二:
我又研究了一下"IsoDatetimeConverter",发现它的日期格式其实是由于内部DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"导致,而它也提供了修改日期样式的属性"DateTimeFormat",只要我们按照这种格式来写就OK了.

复制代码
            Staff jack = new Staff { Name = "Jack", Age = 30, Gender = "Male",
                DepartmentName = "Personnel Department", BirthDate = new DateTime(1982,2,12), EmploymentDate = new DateTime(2010,12,12) };
            IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy'年'MM'月'dd'日'" };
            string json = JsonConvert.SerializeObject(jack,dtConverter);
            Console.WriteLine(json);
复制代码

 结果:

6.FAQ
1.如何自定义序列化的字段名称?
默认情况下,Json.Net序列化后结果中的字段名称和类中属性的名称一致.如果想自定义序列化后的字段名称,可以使用JsonProperty.例如:
复制代码
 public class Person
 {
       public int Id { get; set; }

       public string Name { get; set; }
 }
复制代码

默认序列化的结果为: {"Id":1,"Name":"杨过"},如果不想用默认的字段名称,可以使用如下方式:

复制代码
public class Person
{
       [JsonProperty(PropertyName = "PersonId")]
       public int Id { get; set; }

       [JsonProperty(PropertyName = "PersonName")]
       public string Name { get; set; }
}
复制代码

这样序列化的结果为:{"PersonId":1,"PersonName":"杨过"}

目录
相关文章
|
24天前
|
开发框架 前端开发 JavaScript
ASP.NET Web Pages - 教程
ASP.NET Web Pages 是一种用于创建动态网页的开发模式,采用HTML、CSS、JavaScript 和服务器脚本。本教程聚焦于Web Pages,介绍如何使用Razor语法结合服务器端代码与前端技术,以及利用WebMatrix工具进行开发。适合初学者入门ASP.NET。
|
1月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
2月前
|
开发框架 NoSQL MongoDB
C#/.NET/.NET Core开发实战教程集合
C#/.NET/.NET Core开发实战教程集合
|
2月前
|
存储 NoSQL API
.NET NoSQL 嵌入式数据库 LiteDB 使用教程
.NET NoSQL 嵌入式数据库 LiteDB 使用教程~
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
51 7
|
3月前
|
SQL 关系型数据库 数据库
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
七天.NET 8操作SQLite入门到实战详细教程(选型、开发、发布、部署)
|
4月前
|
JSON 开发框架 JavaScript
【Azure Developer】使用.Net Core解析JSON的笔记
【Azure Developer】使用.Net Core解析JSON的笔记
|
4月前
|
开发框架 .NET API
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
215 3
|
4月前
|
开发框架 JavaScript .NET
Vue与ASP.NET Core Web Api设置localhost与本地ip地址皆可访问
Vue与ASP.NET Core Web Api设置localhost与本地ip地址皆可访问
55 0
|
6月前
|
JSON 开发框架 API
【推荐100个unity插件之20】一个强大的JSON处理库——Newtonsoft.Json(也称为Json.NET)
【推荐100个unity插件之20】一个强大的JSON处理库——Newtonsoft.Json(也称为Json.NET)
565 0