JSON.NET对象序列化示例教程
" JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询。目前已被微软集成于webapi框架之中,因此,熟练掌握JSON.NET相当重要,这篇文章是零度参考官网整理的示例,通过这些示例,可以全面了解JSON.NET提供的功能。
与其它任框架一样,要使用JSON.NET框架,首先需要在您的项目中引用它,框架可以点击这里到GITHUB开源社区下载,然后根据您项目的版本直接引用newtonsoft.json.dll即可,更快捷的方法是通过NUGET提供的包管理器来进行安装,安装方式如下所示。打开VisualStudio2013,单击〖工具〗,在〖NuGet程序包管理器〗菜单下选中〖程序包管理器控制台〗,在控制台输入以下命令后,回车即可自动安装最新版。
<span style=color: blue;>Install-Package Newtonsoft.Json
JSON.NET框架安装完成后,就可以在您的程序中使用它,下面就是零度提供的JSON.NET使用示例,其中绿色代码表示示例的输出结果,为了便于阅读,我们通过Formatting.Indented将代码格式化输出。
1、使用JSON.NET序列化对象
<span style=color: blue;>public class <span style=color: #2b91af;>Account <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Email { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public bool <span style=color: black;>Active { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>DateTime <span style=color: black;>CreatedDate { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>IList<span style=color: black;><<span style=color: blue;>string<span style=color: black;>> Roles { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>Account <span style=color: black;>account = <span style=color: blue;>new <span style=color: #2b91af;>Account <span style=color: black;>{ Email = <span style=color: #a31515;>james@example.com<span style=color: black;>, Active = <span style=color: blue;>true<span style=color: black;>, CreatedDate = <span style=color: blue;>new <span style=color: #2b91af;>DateTime<span style=color: black;>(2013, 1, 20, 0, 0, 0, <span style=color: #2b91af;>DateTimeKind<span style=color: black;>.Utc), Roles = <span style=color: blue;>new <span style=color: #2b91af;>List<span style=color: black;><<span style=color: blue;>string<span style=color: black;>> { <span style=color: #a31515;>User<span style=color: black;>, <span style=color: #a31515;>Admin <span style=color: black;>} }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(account, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ Email: james@example.com, Active: true, CreatedDate: 2013-01-20T00:00:00Z, Roles: [ User, Admin ] }
2、使用JSON.NET序列化List集合
<span style=color: #2b91af;>List<span style=color: black;><<span style=color: blue;>string<span style=color: black;>> videogames = <span style=color: blue;>new <span style=color: #2b91af;>List<span style=color: black;><<span style=color: blue;>string<span style=color: black;>> { <span style=color: #a31515;>零度<span style=color: black;>, <span style=color: #a31515;>分享<span style=color: black;>, <span style=color: #a31515;>编程之美 <span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(videogames); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>[零度,分享,编程之美]
3、使用JSON.NET序列化dictionary字典
<span style=color: blue;>var <span style=color: black;>points = <span style=color: blue;>new <span style=color: #2b91af;>Dictionary<span style=color: black;><<span style=color: blue;>string<span style=color: black;>, <span style=color: blue;>int<span style=color: black;>> { { <span style=color: #a31515;>James<span style=color: black;>, 9001 }, { <span style=color: #a31515;>Jo<span style=color: black;>, 3474 }, { <span style=color: #a31515;>Jess<span style=color: black;>, 11926 } }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(points, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ James: 9001, Jo: 3474, Jess: 11926 }
4、将序列化结果保存到指定的文件
<span style=color: blue;>public class <span style=color: #2b91af;>Movie <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public int <span style=color: black;>Year { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>Movie <span style=color: black;>movie = <span style=color: blue;>new <span style=color: #2b91af;>Movie <span style=color: black;>{ Name = <span style=color: #a31515;>Bad Boys<span style=color: black;>, Year = 1995 }; <span style=color: blue;>using <span style=color: black;>(<span style=color: #2b91af;>StreamWriter <span style=color: black;>file = <span style=color: #2b91af;>File<span style=color: black;>.CreateText(<span style=color: #a31515;>@e:\movie.json<span style=color: black;>)) { <span style=color: #2b91af;>JsonSerializer <span style=color: black;>serializer = <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializer<span style=color: black;>(); serializer.Serialize(file, movie); }
5、基于枚举类型的JsonConverters转换器
<span style=color: blue;>public enum <span style=color: #2b91af;>StringComparison <span style=color: black;>
<span style=color: #2b91af;>List<span style=color: black;><<span style=color: #2b91af;>StringComparison<span style=color: black;>> stringComparisons = <span style=color: blue;>new <span style=color: #2b91af;>List<span style=color: black;><<span style=color: #2b91af;>StringComparison<span style=color: black;>> { <span style=color: #2b91af;>StringComparison<span style=color: black;>.CurrentCulture, <span style=color: #2b91af;>StringComparison<span style=color: black;>.InvariantCulture }; <span style=color: blue;>string <span style=color: black;>jsonWithoutConverter = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(stringComparisons); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(jsonWithoutConverter);
<span style=color: green;>[0,2]
<span style=color: blue;>string <span style=color: black;>jsonWithConverter = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(stringComparisons, <span style=color: blue;>new <span style=color: #2b91af;>StringEnumConverter<span style=color: black;>()); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(jsonWithConverter);
<span style=color: green;>[CurrentCulture,InvariantCulture]
<span style=color: blue;>var <span style=color: black;>result = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>List<span style=color: black;><<span style=color: #2b91af;>StringComparison<span style=color: black;>>>(jsonWithConverter, <span style=color: blue;>new <span style=color: #2b91af;>StringEnumConverter<span style=color: black;>()); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(<span style=color: blue;>string<span style=color: black;>.Join(<span style=color: #a31515;>"", ""<span style=color: black;>, result.Select(c => c.ToString())));
<span style=color: green;>CurrentCulture, InvariantCulture
6、通过JRaw将JS函数序列化到JSON中
<span style=color: blue;>public class <span style=color: #2b91af;>JavaScriptSettings <span style=color: black;>{ <span style=color: blue;>public <span style=color: #2b91af;>JRaw <span style=color: black;>OnLoadFunction { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>JRaw <span style=color: black;>OnUnloadFunction { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>JavaScriptSettings <span style=color: black;>settings = <span style=color: blue;>new <span style=color: #2b91af;>JavaScriptSettings <span style=color: black;>{ OnLoadFunction = <span style=color: blue;>new <span style=color: #2b91af;>JRaw<span style=color: black;>(<span style=color: #a31515;>OnLoad<span style=color: black;>), OnUnloadFunction = <span style=color: blue;>new <span style=color: #2b91af;>JRaw<span style=color: black;>(<span style=color: #a31515;>function(e) { alert(e); }<span style=color: black;>) }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(settings, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ OnLoadFunction: OnLoad, OnUnloadFunction: function(e) { alert(e); } }
7、使用JSON.NET反序列化对象
<span style=color: blue;>public class <span style=color: #2b91af;>Account <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Email { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public bool <span style=color: black;>Active { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>DateTime <span style=color: black;>CreatedDate { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>IList<span style=color: black;><<span style=color: blue;>string<span style=color: black;>> Roles { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ 'Email': 'james@example.com', 'Active': true, 'CreatedDate': '2013-01-20T00:00:00Z', 'Roles': [ 'User', 'Admin' ] }<span style=color: black;>; <span style=color: #2b91af;>Account <span style=color: black;>account = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>Account<span style=color: black;>>(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(account.Email);
<span style=color: green;>james@example.com
8、使用JSON.NET反序列化List集合
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@['Starcraft','Halo','Legend of Zelda']<span style=color: black;>; <span style=color: #2b91af;>List<span style=color: black;><<span style=color: blue;>string<span style=color: black;>> videogames = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>List<span style=color: black;><<span style=color: blue;>string<span style=color: black;>>>(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(<span style=color: blue;>string<span style=color: black;>.Join(<span style=color: #a31515;>"", ""<span style=color: black;>, videogames));
<span style=color: green;>Starcraft, Halo, Legend of Zelda
9、使用JSON.NET反序列化dictionary字典
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{'href': 'www.xcode.me','target': '_blank'}<span style=color: black;>; <span style=color: blue;>var <span style=color: black;>htmlAttributes = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>Dictionary<span style=color: black;><<span style=color: blue;>string<span style=color: black;>, <span style=color: blue;>string<span style=color: black;>>>(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(htmlAttributes[<span style=color: #a31515;>href<span style=color: black;>]);
<span style=color: green;>www.xcode.me
10、序列化var匿名类型
有时候,我们并不需要先定义一个类,然后new一个对象后再进行序列化,JSON.NET支持匿名类型的序列化和反序列化。
<span style=color: blue;>var <span style=color: black;>definition = <span style=color: blue;>new <span style=color: black;>{ Name = <span style=color: #a31515;>零度编程<span style=color: black;>, Site = <span style=color: #a31515;>www.xcode.me <span style=color: black;>}; <span style=color: blue;>var <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(definition); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ Name: 零度编程, Site: www.xcode.me }
<span style=color: blue;>var <span style=color: black;>definition = <span style=color: blue;>new <span style=color: black;>{ Name = <span style=color: #a31515;><span style=color: black;>, Site = <span style=color: #a31515;> <span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{'Name':'零度编程','Site':'www.xcode.me'}<span style=color: black;>; <span style=color: blue;>var <span style=color: black;>webSite = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeAnonymousType(json, definition); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(webSite.Name);
<span style=color: green;>零度编程
11、用新JSON字符串填充指定对象的属性值
<span style=color: #2b91af;>Account <span style=color: black;>account = <span style=color: blue;>new <span style=color: #2b91af;>Account <span style=color: black;>{ Email = <span style=color: #a31515;>james@example.com<span style=color: black;>, Active = <span style=color: blue;>true<span style=color: black;>, CreatedDate = <span style=color: blue;>new <span style=color: #2b91af;>DateTime<span style=color: black;>(2013, 1, 20, 0, 0, 0, <span style=color: #2b91af;>DateTimeKind<span style=color: black;>.Utc), Roles = <span style=color: blue;>new <span style=color: #2b91af;>List<span style=color: black;><<span style=color: blue;>string<span style=color: black;>>{<span style=color: #a31515;>User<span style=color: black;>,<span style=color: #a31515;>Admin<span style=color: black;>} }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{'Active': false, 'Roles': ['Expired']}<span style=color: black;>; <span style=color: #2b91af;>JsonConvert<span style=color: black;>.PopulateObject(json, account); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(account.Active);
<span style=color: green;>false
上面的示例中,account对象的Active值首次设置为true,可通过PopulateObject方法通过json字符串重新填充Active属性和Roles属性。
12、使用JSON.NET反序列化时可指定构造函数
首先我们定义如下的类型,我们希望JSON.NET反序列化对象时使用第2个构造函数,我们将第一个默认构造函数屏蔽,标记为私有private修饰符。第2个构造函数需要指定一个website对象作为参数,如果提供的参数为null则抛出异常:
<span style=color: blue;>public class <span style=color: #2b91af;>Website <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Url { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>private <span style=color: black;>Website() <span style=color: blue;>public <span style=color: black;>Website(<span style=color: #2b91af;>Website <span style=color: black;>website) { <span style=color: blue;>if <span style=color: black;>(website == <span style=color: blue;>null<span style=color: black;>) <span style=color: blue;>throw new <span style=color: #2b91af;>ArgumentNullException<span style=color: black;>(<span style=color: #a31515;>website<span style=color: black;>); Url = website.Url; } }
现在使用一般的方式反序列化一个JSON字符串。
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{'Url':'http://www.xcode.me'}<span style=color: black;>; <span style=color: blue;>try <span style=color: black;>{ <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>Website<span style=color: black;>>(json); } <span style=color: blue;>catch <span style=color: black;>(<span style=color: #2b91af;>Exception <span style=color: black;>ex) { <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(ex); }
<span style=color: green;>Value cannot be null.Parameter name: website
我们发现该序列化方法抛出了异常,并没有按照我们预想的方式进行反序列化,JSON.NET提供如下的方式指定公有构造函数。
<span style=color: #2b91af;>Website <span style=color: black;>website = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>Website<span style=color: black;>>(json, <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>{ ConstructorHandling = <span style=color: #2b91af;>ConstructorHandling<span style=color: black;>.AllowNonPublicDefaultConstructor }); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(website.Url);
<span style=color: green;>http://www.xcode.me
另外,JSON.NET提供了指定任何构造函数的JsonConstructorAttribute特性,只需要在构造函数上标记,即可指定构造函数。
<span style=color: blue;>public class <span style=color: #2b91af;>User <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>UserName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>private set<span style=color: black;>; } <span style=color: blue;>public bool <span style=color: black;>Enabled { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>private set<span style=color: black;>; } <span style=color: blue;>public <span style=color: black;>User() [<span style=color: #2b91af;>JsonConstructor<span style=color: black;>] <span style=color: blue;>public <span style=color: black;>User(<span style=color: blue;>string <span style=color: black;>userName, <span style=color: blue;>bool <span style=color: black;>enabled) }
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{UserName: www.xcode.me,Enabled: true}<span style=color: black;>; <span style=color: #2b91af;>User <span style=color: black;>user = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>User<span style=color: black;>>(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(user.UserName);
<span style=color: green;>www.xcode.me
13、当对象的属性为默认值(0或null)时不序列化该属性
<span style=color: blue;>public class <span style=color: #2b91af;>Person <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public int <span style=color: black;>Age { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>Person <span style=color: black;>Partner { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public decimal<span style=color: black;>? Salary { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>Person <span style=color: black;>person = <span style=color: blue;>new <span style=color: #2b91af;>Person<span style=color: black;>(); <span style=color: blue;>string <span style=color: black;>jsonIncludeDefaultValues = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(person, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(jsonIncludeDefaultValues);
<span style=color: green;>{ Name: null, Age: 0, Partner: null, Salary: null }
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(person, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented, <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>{ DefaultValueHandling = <span style=color: #2b91af;>DefaultValueHandling<span style=color: black;>.Ignore }); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>
14、反序列化时JSON属性与对象属性的数量必须一致
默认情况下,JSON.NET反序列化并不要求JSON属性的数量与对象属性的数量相等,也就是始终保持有则序列化,无则不序列化的原则,不会抛出异常。但是,我们的需求并非这样,我们希望属性数量不等或者未提供值时,抛出异常,而不是正常反序列化,可以这样。
<span style=color: blue;>public class <span style=color: #2b91af;>Account <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>FullName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public bool <span style=color: black;>Deleted { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ 'FullName': 'Dan Deleted', 'Deleted': true, 'DeletedDate': '2013-01-20T00:00:00' }<span style=color: black;>;
</span><span style=""color: blue;"">try
</span><span style=""color: black;"">{
</span><span style=""color: #2b91af;"">JsonConvert</span><span style=""color: black;"">.DeserializeObject<</span><span style=""color: #2b91af;"">Account</span><span style=""color: black;"">>(json, </span><span style=""color: blue;"">new </span><span style=""color: #2b91af;"">JsonSerializerSettings
</span><span style=""color: black;"">{
MissingMemberHandling = </span><span style=""color: #2b91af;"">MissingMemberHandling</span><span style=""color: black;"">.Error
});
}
</span><span style=""color: blue;"">catch </span><span style=""color: black;"">(</span><span style=""color: #2b91af;"">JsonSerializationException </span><span style=""color: black;"">ex)
{
</span><span style=""color: #2b91af;"">Console</span><span style=""color: black;"">.WriteLine(ex.Message);
}</span>
<span style=color: green;>Could not find member 'DeletedDate' on object of type 'Account'. Path 'DeletedDate', line 4, position 23.
这样,当未全部指定对象的属性时,就会抛出异常,而不是部分属性序列化。
15、JSON.NET中忽略null值得处理器
<span style=color: blue;>public class <span style=color: #2b91af;>Person <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public int <span style=color: black;>Age { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>Person <span style=color: black;>Partner { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public decimal<span style=color: black;>? Salary { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>Person <span style=color: black;>person = <span style=color: blue;>new <span style=color: #2b91af;>Person <span style=color: black;>{ Name = <span style=color: #a31515;>Nigal Newborn<span style=color: black;>, Age = 1 }; <span style=color: blue;>string <span style=color: black;>jsonIncludeNullValues = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(person, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(jsonIncludeNullValues);
<span style=color: green;>{ Name: Nigal Newborn, Age: 1, Partner: null, Salary: null }
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(person, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented, <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>{ NullValueHandling = <span style=color: #2b91af;>NullValueHandling<span style=color: black;>.Ignore }); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ Name: Nigal Newborn, Age: 1 }
在上面的示例中,默认情况下JSON.NET会将对象的null属性值序列化为JSON中null值。当对象属性值为null时,可忽略序列化,只需要指定NullValueHandling即可,另外有一种场景是,当对象属性值为null时,需要替换为空字符串双引号,如何替换,请点击这里参阅零度的文章。
16、JSON.NET中循环引用的处理方法
有的对象具有循环引用,对象的属性是对象本身,这会导致JSON.NET进入无限死循环,我们需要指定ReferenceLoopHandling打破这种循环引用。
<span style=color: blue;>public class <span style=color: #2b91af;>Employee <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>Employee <span style=color: black;>Manager { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>Employee <span style=color: black;>joe = <span style=color: blue;>new <span style=color: #2b91af;>Employee <span style=color: black;>{ Name = <span style=color: #a31515;>Joe User <span style=color: black;>}; <span style=color: #2b91af;>Employee <span style=color: black;>mike = <span style=color: blue;>new <span style=color: #2b91af;>Employee <span style=color: black;>{ Name = <span style=color: #a31515;>Mike Manager <span style=color: black;>}; joe.Manager = mike; mike.Manager = mike; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(joe, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented, <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>{ ReferenceLoopHandling = <span style=color: #2b91af;>ReferenceLoopHandling<span style=color: black;>.Ignore }); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ Name: Joe User, Manager: { Name: Mike Manager } }
17、通过ContractResolver指定属性名首字母小写
通常,在.NET中属性采用PascalCase规则(首字母大写),在JavaScript中属性名使用CamelCase规则(首字母小写),我们希望序列化后的JSON字符串符合CamelCase规则,JSON.NET提供的ContractResolver可以设置属性名小写序列化,更灵活的设置请点击这里参阅零度的文章。
<span style=color: blue;>public class <span style=color: #2b91af;>Person <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>FirstName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public string <span style=color: black;>LastName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; }
</span><span style=""color: blue;"">public string </span><span style=""color: black;"">FullName
{
</span><span style=""color: blue;"">get </span><span style=""color: black;"">{ </span><span style=""color: blue;"">return </span><span style=""color: black;"">FirstName + </span><span style=""color: #a31515;"">"" "" </span><span style=""color: black;"">+ LastName; }
}
}</span>
<span style=color: #2b91af;>Person <span style=color: black;>person = <span style=color: blue;>new <span style=color: #2b91af;>Person <span style=color: black;>{ FirstName = <span style=color: #a31515;>Sarah<span style=color: black;>, LastName = <span style=color: #a31515;>Security <span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(person, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented, <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>{ ContractResolver = <span style=color: blue;>new <span style=color: #2b91af;>CamelCasePropertyNamesContractResolver<span style=color: black;>() }); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ firstName: Sarah, lastName: Security, fullName: Sarah Security }
18、JSON.NET中通过特性序列化枚举类型
<span style=color: blue;>public enum <span style=color: #2b91af;>UserStatus <span style=color: black;>{ NotConfirmed, Active, Deleted }
</span><span style=""color: blue;"">public class </span><span style=""color: #2b91af;"">User
</span><span style=""color: black;"">{
</span><span style=""color: blue;"">public string </span><span style=""color: black;"">UserName { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
[</span><span style=""color: #2b91af;"">JsonConverter</span><span style=""color: black;"">(</span><span style=""color: blue;"">typeof</span><span style=""color: black;"">(</span><span style=""color: #2b91af;"">StringEnumConverter</span><span style=""color: black;"">))]
</span><span style=""color: blue;"">public </span><span style=""color: #2b91af;"">UserStatus </span><span style=""color: black;"">Status { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
}</span>
默认情况下JSON.NET针对枚举类型输出对应的INT值,如果需要输出具有语义的字符串,可指定JsonConverter的值为StringEnumConverter类型。
<span style=color: #2b91af;>User <span style=color: black;>user = <span style=color: blue;>new <span style=color: #2b91af;>User <span style=color: black;>{ UserName = <span style=color: #a31515;>@零度编程<span style=color: black;>, Status = <span style=color: #2b91af;>UserStatus<span style=color: black;>.Deleted }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(user, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ UserName: 零度编程, Status: Deleted }
19、指定需要序列化的属性
通过JsonProperty指定哪些字段应该被序列化,需要序列化则标记,不需要序列化则取消标记。
<span style=color: black;>[<span style=color: #2b91af;>JsonObject<span style=color: black;>(<span style=color: #2b91af;>MemberSerialization<span style=color: black;>.OptIn)] <span style=color: blue;>public class <span style=color: #2b91af;>File <span style=color: black;>{ <span style=color: green;>//Id不需要序列化 <span style=color: blue;>public <span style=color: #2b91af;>Guid <span style=color: black;>Id { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; }
[</span><span style=""color: #2b91af;"">JsonProperty</span><span style=""color: black;"">]
</span><span style=""color: blue;"">public string </span><span style=""color: black;"">Name { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
[</span><span style=""color: #2b91af;"">JsonProperty</span><span style=""color: black;"">]
</span><span style=""color: blue;"">public int </span><span style=""color: black;"">Size { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
}</span>
<span style=color: #2b91af;>File <span style=color: black;>file = <span style=color: blue;>new <span style=color: #2b91af;>File <span style=color: black;>{ Id = <span style=color: #2b91af;>Guid<span style=color: black;>.NewGuid(), Name = <span style=color: #a31515;>xcode.pdf<span style=color: black;>, Size = 50 * 1024 }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(file, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ Name: xcode.pdf, Size: 51200 }
20、序列化对象时指定属性名
序列化对象时,可标记属性的JsonProperty特性,并指定需要序列化为JSON时应有的属性名。
<span style=color: blue;>public class <span style=color: #2b91af;>Videogame <span style=color: black;>{ [<span style=color: #2b91af;>JsonProperty<span style=color: black;>(<span style=color: #a31515;>name<span style=color: black;>)] <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; }
[</span><span style=""color: #2b91af;"">JsonProperty</span><span style=""color: black;"">(</span><span style=""color: #a31515;"">""release_date""</span><span style=""color: black;"">)]
</span><span style=""color: blue;"">public </span><span style=""color: #2b91af;"">DateTime </span><span style=""color: black;"">ReleaseDate { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
}</span>
<span style=color: #2b91af;>Videogame <span style=color: black;>starcraft = <span style=color: blue;>new <span style=color: #2b91af;>Videogame <span style=color: black;>{ Name = <span style=color: #a31515;>Starcraft<span style=color: black;>, ReleaseDate = <span style=color: blue;>new <span style=color: #2b91af;>DateTime<span style=color: black;>(1998, 1, 1) }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(starcraft, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ name: Starcraft, release_date: 1998-01-01T00:00:00 }
21、序列化时指定属性在JSON中的顺序
<span style=color: blue;>public class <span style=color: #2b91af;>Person <span style=color: black;>{ [<span style=color: #2b91af;>JsonProperty<span style=color: black;>(Order = 2)] <span style=color: blue;>public string <span style=color: black;>FirstName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; }
[</span><span style=""color: #2b91af;"">JsonProperty</span><span style=""color: black;"">(Order = 1)]
</span><span style=""color: blue;"">public string </span><span style=""color: black;"">LastName { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
}</span>
<span style=color: #2b91af;>Person <span style=color: black;>person = <span style=color: blue;>new <span style=color: #2b91af;>Person <span style=color: black;>{ FirstName = <span style=color: #a31515;>零度<span style=color: black;>, LastName = <span style=color: #a31515;>编程 <span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(person, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ LastName: 编程, FirstName: 零度 }
22、反序列化指定属性是否必须有值必须不为null
在反序列化一个JSON时,可通过JsonProperty特性的Required指定反序列化行为,当反序列化行为与指定的行为不匹配时,JSON.NET将抛出异常,Required是枚举,Required.Always表示属性必须有值切不能为null,Required.AllowNull表示属性必须有值,但允许为null值。
<span style=color: blue;>public class <span style=color: #2b91af;>Videogame <span style=color: black;>{ [<span style=color: #2b91af;>JsonProperty<span style=color: black;>(Required = <span style=color: #2b91af;>Required<span style=color: black;>.Always)] <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; }
[</span><span style=""color: #2b91af;"">JsonProperty</span><span style=""color: black;"">(Required = </span><span style=""color: #2b91af;"">Required</span><span style=""color: black;"">.AllowNull)]
</span><span style=""color: blue;"">public </span><span style=""color: #2b91af;"">DateTime</span><span style=""color: black;"">? ReleaseDate { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
}</span>
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ 'Name': 'Starcraft III', 'ReleaseDate': null }<span style=color: black;>; <span style=color: #2b91af;>Videogame <span style=color: black;>starcraft = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeObject<<span style=color: #2b91af;>Videogame<span style=color: black;>>(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(starcraft.Name);
<span style=color: green;>Starcraft III
23、通过特性指定null值忽略序列化
<span style=color: blue;>public class <span style=color: #2b91af;>Vessel <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>Name { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public string <span style=color: black;>Class { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; }
[</span><span style=""color: #2b91af;"">JsonProperty</span><span style=""color: black;"">(NullValueHandling = </span><span style=""color: #2b91af;"">NullValueHandling</span><span style=""color: black;"">.Ignore)]
</span><span style=""color: blue;"">public </span><span style=""color: #2b91af;"">DateTime</span><span style=""color: black;"">? LaunchDate { </span><span style=""color: blue;"">get</span><span style=""color: black;"">; </span><span style=""color: blue;"">set</span><span style=""color: black;"">; }
}</span>
<span style=color: #2b91af;>Vessel <span style=color: black;>vessel = <span style=color: blue;>new <span style=color: #2b91af;>Vessel <span style=color: black;>{ Name = <span style=color: #a31515;>Red October<span style=color: black;>, Class = <span style=color: #a31515;>Typhoon <span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(vessel, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ Name: Red October, Class: Typhoon }
24、忽略不需要序列化的属性
并不是对象所有属性都要参与序列化,我们可以使用JsonIgnore特性排除不需要序列化的属性,下面示例中的PasswordHash将被忽略。
<span style=color: blue;>public class <span style=color: #2b91af;>Account <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>FullName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public string <span style=color: black;>EmailAddress { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } [<span style=color: #2b91af;>JsonIgnore<span style=color: black;>] <span style=color: blue;>public string <span style=color: black;>PasswordHash { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: #2b91af;>Account <span style=color: black;>account = <span style=color: blue;>new <span style=color: #2b91af;>Account <span style=color: black;>{ FullName = <span style=color: #a31515;>admin<span style=color: black;>, EmailAddress = <span style=color: #a31515;>admin@xcode.me<span style=color: black;>, PasswordHash = <span style=color: #a31515;>VHdlZXQgJ1FASmFtZXNOSw== <span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(account); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{FullName:admin,EmailAddress:admin@xcode.me}
25、通过特性指定属性的默认序列化值
当属性没有赋值时,默认值一般是null或者0,我们可通过DefaultValue特性改变默认值,可用指定的字符替换,而不是输出null。
<span style=color: blue;>public class <span style=color: #2b91af;>Customer <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>FirstName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } [<span style=color: #2b91af;>DefaultValue<span style=color: black;>(<span style=color: #a31515;>""""<span style=color: black;>)] <span style=color: blue;>public string <span style=color: black;>LastName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: green;>{FirstName:null,LastName:""""}
26、序列化或反序列化时指定日期时间格式
JSON.NET中提供一个名为JsonSerializerSettings的设置对象,可通过此对象设置很多序列化和反序列化的行为,如果要设置JSON.NET序列化输出的日期时间格式,只需要指定格式化字符串即可。默认序列化行为,日期时间格式如下:
<span style=color: blue;>public class <span style=color: #2b91af;>Customer <span style=color: black;>{ <span style=color: blue;>public string <span style=color: black;>FirstName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public string <span style=color: black;>LastName { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } <span style=color: blue;>public <span style=color: #2b91af;>DateTime <span style=color: black;>CreateDate { <span style=color: blue;>get<span style=color: black;>; <span style=color: blue;>set<span style=color: black;>; } }
<span style=color: blue;>var <span style=color: black;>custom = <span style=color: blue;>new <span style=color: #2b91af;>Customer <span style=color: black;>{ FirstName = <span style=color: #a31515;>零度<span style=color: black;>, LastName = <span style=color: #a31515;>编程<span style=color: black;>, CreateDate = <span style=color: #2b91af;>DateTime<span style=color: black;>.Now }; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(custom, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ FirstName: 零度, LastName: 编程, CreateDate: 2015-08-24T17:19:39.0227502+08:00 }
通过JsonSerializerSettings的DateFormatString属性指定日期时间格式:
<span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>settings = <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings<span style=color: black;>(); settings.DateFormatString = <span style=color: #a31515;>yyyy-MM-dd HH:mm:ss<span style=color: black;>; settings.Formatting = <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(custom, settings); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ FirstName: 零度, LastName: 编程, CreateDate: 2015-08-24 17:23:56 }
27、JSON字符串格式化
默认情况下通过JsonConvert.SerializeObject(object value)序列化后的JSON是压缩格式,为了便于阅读,通常需要将JSON字符串格式化处理。
<span style=color: blue;>var <span style=color: black;>value = <span style=color: blue;>new <span style=color: #2b91af;>Customer <span style=color: black;>{ FirstName = <span style=color: #a31515;>零度<span style=color: black;>, LastName = <span style=color: #a31515;>编程<span style=color: black;>}; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(value); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{FirstName:零度,LastName:编程}
<span style=color: #2a2a2a;>以上为指定格式化,将输出压缩版JSON字符串,可通过Formatting.Indented指定格式化输出。
<span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(value, <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
<span style=color: green;>{ FirstName: 零度, LastName: 编程 }
也可以指定JsonSerializerSettings对象的Formatting值为Formatting.Indented进行格式化,与上面的结果等效。
<span style=color: #2b91af;>JsonSerializerSettings <span style=color: black;>settings = <span style=color: blue;>new <span style=color: #2b91af;>JsonSerializerSettings<span style=color: black;>(); settings.Formatting = <span style=color: #2b91af;>Formatting<span style=color: black;>.Indented; <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeObject(value, settings); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);
以上就是JSON.NET的序列化和反序列化示例,下一篇博客将总结JSON.NET与LINQ的结合,希望对您有所帮助。"