JSON.NET与LINQ序列化示例教程

2023/7/6 02:13:35

"json-net-logo上一篇博客中,我们演示了JSON.NET提供的最基础功能,这篇文章通过多个示例演示JSON.NET与LINQ的完美结合,让.NET操作JSON变得非常的简单,最后我们还会演示如何通过JSON.NET转换BSON数据、如何实现JSON格式与XML格式的互相转换,让您熟练在.NET中序列化对象。

1、手动创建JSON对象和数组

JSON格式主要包括对象和数组两种形式,在JSON.NET中分别用JArray和JObject表示,属性用JProperty表示,属性值用JValue表示,这些对象都直接或间接继承JToken抽象类,而且都有一个ToString方法,该方法用于直接输出元素的JSON字符串表示形式,我们可以通过JArray和JObject手动创建JSON并序列化,使用方式非常灵活。

<span style=color: #2b91af;>JArray <span style=color: black;>array = <span style=color: blue;>new <span style=color: #2b91af;>JArray<span style=color: black;>(); array.Add(<span style=color: #a31515;>Manual text<span style=color: black;>); array.Add(<span style=color: blue;>new <span style=color: #2b91af;>DateTime<span style=color: black;>(2000, 5, 23)); <span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: blue;>new <span style=color: #2b91af;>JObject<span style=color: black;>(); o[<span style=color: #a31515;>MyArray<span style=color: black;>] = array; <span style=color: blue;>string <span style=color: black;>json = o.ToString();

<span style=color: green;>{ MyArray: [ Manual text, 2000-05-23T00:00:00 ] }

2、用集合的方式初始化JArray数组和JObject对象

<span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: blue;>new <span style=color: #2b91af;>JObject <span style=color: black;>{ { <span style=color: #a31515;>Cpu<span style=color: black;>, <span style=color: #a31515;>Intel <span style=color: black;>}, { <span style=color: #a31515;>Memory<span style=color: black;>, 32 }, { <span style=color: #a31515;>Drives<span style=color: black;>, <span style=color: blue;>new <span style=color: #2b91af;>JArray <span style=color: black;>{ <span style=color: #a31515;>DVD<span style=color: black;>, <span style=color: #a31515;>SSD <span style=color: black;>} } }; <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString());

<span style=color: green;>{ Cpu: Intel, Memory: 32, Drives: [ DVD, SSD ] }

3、使用动态类型dynamic类型创建JSON数组和对象

C#中的动态类型dynamic允许开发者动态构造对象,这些动态构造的对象在运行时被解析执行,JSON.NET支持动态类型,无需定义类,即可构造JSON,这一些就像在JavaScript中编写一个对象那样简单,正是因为动态类型在运行时才被解析,所以,在开发工具中不能检查因书写而导致错误,这点一定要注意。

<span style=color: blue;>dynamic <span style=color: black;>product = <span style=color: blue;>new <span style=color: #2b91af;>JObject<span style=color: black;>(); product.ProductName = <span style=color: #a31515;>Elbow Grease<span style=color: black;>; product.Enabled = <span style=color: blue;>true<span style=color: black;>; product.Price = 4.90m; product.StockCount = 9000; product.StockValue = 44100; product.Tags = <span style=color: blue;>new <span style=color: #2b91af;>JArray<span style=color: black;>(<span style=color: #a31515;>Real<span style=color: black;>, <span style=color: #a31515;>OnSale<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(product.ToString());

<span style=color: green;>{ ProductName: Elbow Grease, Enabled: true, Price: 4.90, StockCount: 9000, StockValue: 44100, Tags: [ Real, OnSale ] }

4、使用JTokenWriter创建对象和数组

<span style=color: #2b91af;>JTokenWriter <span style=color: black;>writer = <span style=color: blue;>new <span style=color: #2b91af;>JTokenWriter<span style=color: black;>(); writer.WriteStartObject(); writer.WritePropertyName(<span style=color: #a31515;>name1<span style=color: black;>); writer.WriteValue(<span style=color: #a31515;>value1<span style=color: black;>); writer.WritePropertyName(<span style=color: #a31515;>name2<span style=color: black;>); writer.WriteStartArray(); writer.WriteValue(1); writer.WriteValue(2); writer.WriteEndArray(); writer.WriteEndObject(); <span style=color: #2b91af;>JObject <span style=color: black;>o = (<span style=color: #2b91af;>JObject<span style=color: black;>)writer.Token; <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString());

<span style=color: green;>{ name1: value1, name2: [ 1, 2 ] }

5、使用对象创建JSON对象和数组

JToken、JObject和JArray都提供一个名为FromObject的方法,允许通过一个对象来创建JSON对象。

<span style=color: #2b91af;>Computer <span style=color: black;>computer = <span style=color: blue;>new <span style=color: #2b91af;>Computer <span style=color: black;>{ Cpu = <span style=color: #a31515;>Intel<span style=color: black;>, Memory = 32, Drives = <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;>DVD<span style=color: black;>, <span style=color: #a31515;>SSD <span style=color: black;>} }; <span style=color: #2b91af;>JObject <span style=color: black;>o = (<span style=color: #2b91af;>JObject<span style=color: black;>)<span style=color: #2b91af;>JToken<span style=color: black;>.FromObject(computer); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString());

<span style=color: green;>{ Cpu: Intel, Memory: 32, Drives: [ DVD, SSD ] }

<span style=color: #2b91af;>JArray <span style=color: black;>a = (<span style=color: #2b91af;>JArray<span style=color: black;>)<span style=color: #2b91af;>JToken<span style=color: black;>.FromObject(computer.Drives); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(a.ToString());

<span style=color: green;>[ DVD, SSD ]

6、使用字符串创建JSON对象和数组

<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@['Small', 'Medium','Large']<span style=color: black;>; <span style=color: #2b91af;>JArray <span style=color: black;>a = <span style=color: #2b91af;>JArray<span style=color: black;>.Parse(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(a.ToString());

<span style=color: green;>[ Small, Medium, Large ]

<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ CPU: 'Intel', Drives: [ 'DVD read/writer', '500 gigabyte hard drive' ] }<span style=color: black;>; <span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: #2b91af;>JObject<span style=color: black;>.Parse(json); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString());

<span style=color: green;>{ CPU: Intel, Drives: [ DVD read/writer, 500 gigabyte hard drive ] }

7、使用JToken转换JSON字符串

在示例1中,我们已经说明JToken类型,它是JSON.NET的核心,几乎所有的JSON元素都继承于JToken抽象类,虽然JToken是抽象类,但它也提供一些很有用的基础方法,可以转换一段字符串并判断它应有的JSON类型。

<span style=color: #2b91af;>JToken <span style=color: black;>t1 = <span style=color: #2b91af;>JToken<span style=color: black;>.Parse(<span style=color: #a31515;><span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(t1.Type); <span style=color: green;>// Object

<span style=color: #2b91af;>JToken <span style=color: black;>t2 = <span style=color: #2b91af;>JToken<span style=color: black;>.Parse(<span style=color: #a31515;>[]<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(t2.Type); <span style=color: green;>// Array

<span style=color: #2b91af;>JToken <span style=color: black;>t3 = <span style=color: #2b91af;>JToken<span style=color: black;>.Parse(<span style=color: #a31515;>null<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(t3.Type); <span style=color: green;>// Null

<span style=color: #2b91af;>JToken <span style=color: black;>t4 = <span style=color: #2b91af;>JToken<span style=color: black;>.Parse(<span style=color: #a31515;>@'A string!'<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(t4.Type); <span style=color: green;>// String

8、动态修改JSON对象和数组

<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ 'channel': { 'title': 'Star Wars', 'link': 'www.xcode.me', 'description': 'Star Wars blog.', 'obsolete': 'Obsolete value', 'item': [] } }<span style=color: black;>; <span style=color: #2b91af;>JObject <span style=color: black;>rss = <span style=color: #2b91af;>JObject<span style=color: black;>.Parse(json); <span style=color: #2b91af;>JObject <span style=color: black;>channel = (<span style=color: #2b91af;>JObject<span style=color: black;>)rss[<span style=color: #a31515;>channel<span style=color: black;>]; channel[<span style=color: #a31515;>title<span style=color: black;>] = ((<span style=color: blue;>string<span style=color: black;>)channel[<span style=color: #a31515;>title<span style=color: black;>]).ToUpper(); channel[<span style=color: #a31515;>description<span style=color: black;>] = ((<span style=color: blue;>string<span style=color: black;>)channel[<span style=color: #a31515;>description<span style=color: black;>]).ToUpper(); channel.Property(<span style=color: #a31515;>obsolete<span style=color: black;>).Remove(); channel.Property(<span style=color: #a31515;>description<span style=color: black;>).AddAfterSelf(<span style=color: blue;>new <span style=color: #2b91af;>JProperty<span style=color: black;>(<span style=color: #a31515;>new<span style=color: black;>, <span style=color: #a31515;>New value<span style=color: black;>)); <span style=color: #2b91af;>JArray <span style=color: black;>item = (<span style=color: #2b91af;>JArray<span style=color: black;>)channel[<span style=color: #a31515;>item<span style=color: black;>]; item.Add(<span style=color: #a31515;>Item 1<span style=color: black;>); item.Add(<span style=color: #a31515;>Item 2<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(rss.ToString());

<span style=color: green;>{ channel: { title: STAR WARS, link: www.xcode.com, description: STAR WARS BLOG., new: New value, item: [ Item 1, Item 2 ] } }

9、合并两个JSON对象

<span style=color: #2b91af;>JObject <span style=color: black;>o1 = <span style=color: #2b91af;>JObject<span style=color: black;>.Parse(<span style=color: #a31515;>@{ 'FirstName': 'John', 'LastName': 'Smith', 'Enabled': false, 'Roles': [ 'User' ] }<span style=color: black;>); <span style=color: #2b91af;>JObject <span style=color: black;>o2 = <span style=color: #2b91af;>JObject<span style=color: black;>.Parse(<span style=color: #a31515;>@{ 'Enabled': true, 'Roles': [ 'User', 'Admin' ] }<span style=color: black;>); o1.Merge(o2, <span style=color: blue;>new <span style=color: #2b91af;>JsonMergeSettings <span style=color: black;>{ MergeArrayHandling = <span style=color: #2b91af;>MergeArrayHandling<span style=color: black;>.Union }); <span style=color: blue;>string <span style=color: black;>json = o1.ToString();

<span style=color: green;>{ FirstName: John, LastName: Smith, Enabled: true, Roles: [ User, Admin ] }

这里要特别说明的是JsonMergeSettings,该对象用于设置合并时的行为,MergeArrayHandling是枚举,可设置为Concat(连接数组)、Union(跳过存在的元素,添加不存在的元素)、Replace(替换所有数组项)和Merge(根据数组索引将数组项合并在一起)。

10、使用动态类型dynamic查询JSON对象

<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@[ { 'Title': 'Json.NET is awesome!', 'Author': { 'Name': 'James Newton-King', 'Twitter': '@JamesNK', 'Picture': '/jamesnk.png' }, 'Date': '2013-01-23T19:30:00' } ]<span style=color: black;>;

<span style=color: blue;>dynamic <span style=color: black;>blogPosts = <span style=color: #2b91af;>JArray<span style=color: black;>.Parse(json); <span style=color: blue;>dynamic <span style=color: black;>blogPost = blogPosts[0]; <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(blogPost.Title);

<span style=color: green;>Json.NET is awesome!

11、使用ToObject将JSON对象或数组转换成C#对象

<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ 'd': [ { 'Name': 'John Smith' }, { 'Name': 'Mike Smith' } ] }<span style=color: black;>; <span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: #2b91af;>JObject<span style=color: black;>.Parse(json); <span style=color: #2b91af;>JArray <span style=color: black;>a = (<span style=color: #2b91af;>JArray<span style=color: black;>)o[<span style=color: #a31515;>d<span style=color: black;>]; <span style=color: #2b91af;>IList<span style=color: black;><<span style=color: #2b91af;>Person<span style=color: black;>> person = a.ToObject<<span style=color: #2b91af;>IList<span style=color: black;><<span style=color: #2b91af;>Person<span style=color: black;>>>(); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(person[1].Name);

<span style=color: green;>Mike Smith

12、通过属性遍历JObject对象

<span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: blue;>new <span style=color: #2b91af;>JObject <span style=color: black;>{ { <span style=color: #a31515;>name1<span style=color: black;>, <span style=color: #a31515;>value1 <span style=color: black;>}, { <span style=color: #a31515;>name2<span style=color: black;>, <span style=color: #a31515;>value2 <span style=color: black;>} }; <span style=color: blue;>foreach <span style=color: black;>(<span style=color: #2b91af;>JProperty <span style=color: black;>property <span style=color: blue;>in <span style=color: black;>o.Properties()) { <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(property.Name + <span style=color: #a31515;>"" - "" <span style=color: black;>+ property.Value); }

<span style=color: green;>name1 - value1 name2 - value2

<span style=color: blue;>foreach <span style=color: black;>(<span style=color: #2b91af;>KeyValuePair<span style=color: black;><<span style=color: blue;>string<span style=color: black;>, <span style=color: #2b91af;>JToken<span style=color: black;>> property <span style=color: blue;>in <span style=color: black;>o) { <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(property.Key + <span style=color: #a31515;>"" - "" <span style=color: black;>+ property.Value); }

<span style=color: green;>name1 - value1 name2 - value2

13、使用ToString方法进行JSON序列化

在JSON.NET中ToString方法会输出针对当前JSON对象的字符串表示形式,通过这个特点我们可以序列化对象,默认情况下会输出格式化后的JSON字符串,ToString方法提供一些重载,允许开发灵活配置序列化行为。

<span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: #2b91af;>JObject<span style=color: black;>.Parse(<span style=color: #a31515;>@{'string1':'value','integer2':99,'datetime3':'2000-05-23T00:00:00'}<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString());

<span style=color: green;>{ string1: value, integer2: 99, datetime3: 2000-05-23T00:00:00 }

ToString方法也提供一个是否格式化重载方法,下面的示例演示输出压缩后的JSON字符串。

<span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString(<span style=color: #2b91af;>Formatting<span style=color: black;>.None));

<span style=color: green;>{string1:value,integer2:99,datetime3:2000-05-23T00:00:00}

<span style=color: #2a2a2a;>下面的代码演示通过ToString方法提供的重载将日期格式化为JavaScript中的日期对象,这样的JSON在JS中就可以直接使用日期。

<span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(o.ToString(<span style=color: #2b91af;>Formatting<span style=color: black;>.None, <span style=color: blue;>new <span style=color: #2b91af;>JavaScriptDateTimeConverter<span style=color: black;>()));

<span style=color: green;>{string1:value,integer2:99,datetime3:new Date(959032800000)}

14、JSON.NET支持BSON格式的序列化和反序列化

BSON是一种类似于JSON格式,是一种二进制形式存储格式,简称BinaryJSON,它和JSON一样,支持内嵌的对象和数组,BSON可以做为网络数据交换的一种存储形式,它的优点是灵活性高,但它的缺点是空间利用率不是很理想,JSON.NET也支持BSON的序列化和反序列化。

<span style=color: blue;>byte<span style=color: black;>[] data = <span style=color: #2b91af;>Convert<span style=color: black;>.FromBase64String(<span style=color: #a31515;>KQAAAAJuYW1lMQAHAAAAdmFsdWUxAAJuYW1lMgAHAAAAdmFsdWUyAAA=<span style=color: black;>); <span style=color: #2b91af;>MemoryStream <span style=color: black;>ms = <span style=color: blue;>new <span style=color: #2b91af;>MemoryStream<span style=color: black;>(data); <span style=color: #2b91af;>JObject <span style=color: black;>o; <span style=color: blue;>using <span style=color: black;>(<span style=color: #2b91af;>BsonReader <span style=color: black;>reader = <span style=color: blue;>new <span style=color: #2b91af;>BsonReader<span style=color: black;>(ms)) { o = (<span style=color: #2b91af;>JObject<span style=color: black;>)<span style=color: #2b91af;>JToken<span style=color: black;>.ReadFrom(reader); } <span style=color: blue;>string <span style=color: black;>value = (<span style=color: blue;>string<span style=color: black;>)o[<span style=color: #a31515;>name1<span style=color: black;>]; <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(value);

<span style=color: green;>value1

<span style=color: #2b91af;>JObject <span style=color: black;>o = <span style=color: blue;>new <span style=color: #2b91af;>JObject <span style=color: black;>{ { <span style=color: #a31515;>name1<span style=color: black;>, <span style=color: #a31515;>value1 <span style=color: black;>}, { <span style=color: #a31515;>name2<span style=color: black;>, <span style=color: #a31515;>value2 <span style=color: black;>} }; <span style=color: #2b91af;>MemoryStream <span style=color: black;>ms = <span style=color: blue;>new <span style=color: #2b91af;>MemoryStream<span style=color: black;>(); <span style=color: blue;>using <span style=color: black;>(<span style=color: #2b91af;>BsonWriter <span style=color: black;>writer = <span style=color: blue;>new <span style=color: #2b91af;>BsonWriter<span style=color: black;>(ms)) { o.WriteTo(writer); } <span style=color: blue;>string <span style=color: black;>data = <span style=color: #2b91af;>Convert<span style=color: black;>.ToBase64String(ms.ToArray()); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(data);

<span style=color: green;>KQAAAAJuYW1lMQAHAAAAdmFsdWUxAAJuYW1lMgAHAAAAdmFsdWUyAAA=

15、JSON.NET也支持JSON与XML数据格式之间的互转

<span style=color: blue;>string <span style=color: black;>json = <span style=color: #a31515;>@{ '@Id': 1, 'Email': 'james@example.com', 'Active': true, 'CreatedDate': '2013-01-20T00:00:00Z', 'Roles': [ 'User', 'Admin' ], 'Team': { '@Id': 2, 'Name': 'Software Developers', 'Description': 'Creators of fine software products and services.' } }<span style=color: black;>; <span style=color: #2b91af;>XNode <span style=color: black;>node = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.DeserializeXNode(json, <span style=color: #a31515;>Root<span style=color: black;>); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(node.ToString());

<span style=color: green;><Root Id=1> james@example.com true 2013-01-20T00:00:00Z User Admin <Team Id=2> Software Developers Creators of fine software products and services.

<span style=color: blue;>string <span style=color: black;>xml = <span style=color: #a31515;>@ Alan www.xocde.me Louis www.xocde.me <span style=color: black;>; <span style=color: #2b91af;>XmlDocument <span style=color: black;>doc = <span style=color: blue;>new <span style=color: #2b91af;>XmlDocument<span style=color: black;>(); doc.LoadXml(xml); <span style=color: blue;>string <span style=color: black;>json = <span style=color: #2b91af;>JsonConvert<span style=color: black;>.SerializeXmlNode(doc); <span style=color: #2b91af;>Console<span style=color: black;>.WriteLine(json);

<span style=color: green;>{ ?xml: { @version: 1.0, @standalone: no }, root: { person: [ { @id: 1, name: Alan, url: www.xocde.me }, { @id: 2, name: Louis, url: www.xocde.me } ] } }

当然,JSON.NET框架很强大,功能也很多,零度总结都是JSON.NET与LINQ结合的常用示例,希望对您有所帮助。"