首页 > Python基础教程 >
-
C#教程之使用Json.net处理json
http://Json.NET是目前最流行的高效的json .net 框架。
它的优点在于:
- 它在.net对象和json之间提供灵活的序列化
- LINQ to JSON for manually reading and writing JSON
- 比其他.net内建的json序列化组件更高效
- 可以导出结构性强的,容易阅读的json
- 可以把json和xml相互转化
- 支持很多类型的.net, 例如.NET 2, .NET 3.5, .NET 4, .NET 4.5, Silverlight, Windows Phone and Windows 8 Store
在使用之前需要在nuget中安装Newtonsoft.json包,并且在每个cs文件中引用:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
1.序列化和反序列化json
1.1 JsonConvert
在简单的情况下,JsonConvert 提供了 SerializeObject() and DeserializeObject() 方法可以非常容易的用于json序列化。
Product product = new Product();
product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string output = JsonConvert.SerializeObject(product);
Console.WriteLine(output);
//{"Name":"Apple","ExpiryDate":"2008-12-28T00:00:00","Price":3.99,"Sizes":["Small","Medium","Large"]}
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
1.2 JsonSerializer
如果想控制对象如何序列化,我们可以使用JsonSerializer。它包括很多的属性可以用来自定义如何序列化对象。(参考Serialization Settings)
其中:
JsonTextWriter和JsonTextReader可以把json从文件中读出/写入。
Product product = new Product();
product.ExpiryDate = new DateTime(2008, 12, 28);
JsonSerializer serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter());
serializer.NullValueHandling = NullValueHandling.Ignore;
using (StreamWriter sw = new StreamWriter(@"C:\SlaveWorkspace\TestParameters\TestData\json.txt"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, product);
//在json.txt中显示: {"ExpiryDate":new Date(1230393600000),"Price":0.0}
//如果注释掉NullValueHanding, 则内容显示为: {"Name":null,"ExpiryDate":new Da te(1230393600000),"Price":0.0,"Sizes":null}
}
JTokenReader/JTokenWriter可以把对象从Linq到Json转换。
BsonReader/BsonWriter可以把对象和BSON之间转换。
2.Linq to JSON
2.1 从Json 到 Jobject
string json = @"{
CPU: 'Intel',
Drives: [
'DVD read/writer',
'500 gigabyte hard drive'
]
}";
JObject jObject = JObject.Parse(json);
string json2 = @"[
'Small',
'Medium',
'Large'
]";
JArray a = JArray.Parse(json2);
2.2 从文件中读取json
using(StreamReader reader = File.OpenText(@"c:\person.json"))
{
JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader));
// do stuff
}
2.3 手工创建json object
JArray array = new JArray();
JValue text = new JValue("Manual text");
JValue date = new JValue(new DateTime(2000, 5, 23));
array.Add(text);
array.Add(date);
string json = array.ToString();
// [
// "Manual text",
// "2000-05-23T00:00:00"
// ]
2.4 从一个对象创建json object
JObject o = JObject.FromObject(new
{
channel = new
{
title = "abc",
link = "www.baidu.com",
description = "antonio's blog"
}
});
2.5 通过属性名或者集合index从JObject获取值
从JObject/JArray中取值最简单的办法是使用item index,然后把返回的JValue转化为需要的类型。
string json = @"{
'channel': {
'title': 'James Newton-King',
'link': 'http://james.newtonking.com',
'description': 'James Newton-King\'s blog.',
'item': [
{
'title': 'Json.NET 1.3 + New license + Now on CodePlex',
'description': 'Annoucing the release of Json.NET 1.3',
'link': 'http://james.newtonking.com/projects/json-net.aspx',
'categories': [
'Json.NET',
'CodePlex'
]
},
{
'title': 'LINQ to JSON beta',
'description': 'Annoucing LINQ to JSON',
'link': 'http://james.newtonking.com/projects/json-net.aspx',
'categories': [
'Json.NET',
'LINQ'
]
}
]
}
}";
JObject rss = JObject.Parse(json);
string rssTitle = (string)rss["channel"]["title"];
//James Newton-King
string itemTitle = (string)rss["channel"]["item"][0]["title"];
// Json.NET 1.3 + New license + Now on CodePlex
JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
// ["Json.NET", "CodePlex"]
//如果不做转换,每一个element都是JValue类型
IList<string> categoriesText = categories.Select(c => (string)c).ToList();
categoriesText.Where(c=> c.Contains("Pl")).FirstOrDefault(); //CodePlex
2.6 使用linq 查询json
(Linq to JSON是用来操作JSON对象的.可以用于快速查询,修改和创建JSON对象.当JSON对象内容比较复杂,而我们仅仅需要其中的一小部分数据时,可以考虑使用Linq to JSON来读取和修改部分的数据而非反序列化全部.)
Linq to Json 包括一下几种类:
- JObject 用于操作Json对象
- JArray 用于操作Json数组
- JValue 表示值
- JProperty 表示对象中的属性,以key/value 形式
- JToken 用于存放linq to Json查询后的结果
Children方法返回JObject/JArray的子元素值(类型是IEnumerable<JToken>),继而可以使用标准的linq操作符处理。
var postTitles =
from p in rss["channel"]["item"]
select (string)p["title"];
foreach (var item in postTitles)
{
Console.WriteLine(item);
//Json.NET 1.3 + New license + Now on CodePlex
//LINQ to JSON beta
}
var children = rss["channel"].Children();
foreach (JToken result in children)
{
Console.WriteLine(result.ToString());
}
children方法后不能在加toList, 因为返回类型已经是Enumerable(lazy) collection,所以可以直接进行foreach.
下面是一个例子:
这是一个json文件的部分内容,目的是从每一个stage的每一个task中获取到name属性。
在这个基础上,可以把一个Stage下的item抽象成一个taskrow 类,然后反序列化:
using (StreamReader reader = File.OpenText(@"C:\**\AVO Application NSW~"))
{
JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader));
// do stuff
var stages = o.SelectToken("Stages").Children().Select(c => c);
foreach (var stage in stages)
{
var taskRows = from task in stage.SelectToken("Items").Children()
select JsonConvert.DeserializeObject<TaskRow>(task.ToString());
foreach (var taskrow in taskRows)
{
Console.WriteLine(taskrow.name);
}
}
}
反序列化的类是:
public class TaskRow
{
public string name { get; set; }
public string Keyword { get; set; }
public int Importance { get; set; }
}
参考资料:
Json.NET - Newtonsoft
Introduction