標籤:

使用Json.net處理json

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:SlaveWorkspaceTestParametersTestDatajson.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 = "antonios 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-Kings 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-Kingstring itemTitle = (string)rss["channel"]["item"][0]["title"];// Json.NET 1.3 + New license + Now on CodePlexJArray 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


推薦閱讀:

python 調用 API 獲得的JSON如何處理才能獲得我想獲得的內容呢?
JSON 是什麼,在數據交換中有什麼用?
XML/HTML/JSON——數據抓取過程中不得不知的幾個概念
Bumpover.js - 牢固而趁手的數據校驗轉換庫
json是什麼?

TAG:JSON |