在原來解析json數據是,一般都是用反序列化來實現json數據的解讀,這需要首先知道json數據的結構並且建立相應的類才能反序列化,一旦遇到動態的json數據,這種方法就不使用。 為了解決動態解析json數據,微軟有個Newtonsoft.Json封裝類十分好用,里面的JToken直接實現對JSON的增刪改查。
JToken的層次結構是這樣的:
JToken -抽象基類
JContainer - 能夠包含其它JToken的JToken抽象基類
JArray - 表示一個JSON數組(包含一個有序的List)
JObeject - 表示一個JSON對象(包含一個IEnumerable)
JProperty - 表示一個JSON屬性(在JObject中是一個name/JToken鍵值對)
JValue - 表示一個原生JSON值(string,number,boolean,null)
增刪改查:
var cardJson = "['身份證','銀行卡','門禁卡']"; var cardJArray = JArray.Parse(cardJson); var p = new Person { Name="fan",Age=12,Dog=new Dog { Name="奶牛"} };
JObject jobj= JObject.FromObject(p);
//添加屬性 jobj["NickName"] = "fan"; jobj["Wifes"] = new JArray("rose", "lisa"); ((JArray)jobj["Wifes"]).Add( "july"); jobj["Cards"] = cardJArray; //修改屬性 jobj["Name"] = "li"; jobj["Age"] = 9; jobj["Dog"]["Name"] = "阿黃"; ((JArray)jobj["Wifes"])[0] = "roses"; //插入屬性 jobj.Property("Name").AddBeforeSelf(new JProperty("ID", 1)); //刪除屬性 jobj.Property("Age").Remove(); ((JArray)jobj["Wifes"])[2].Remove(); //查找 //遍歷屬性 var props = jobj.Children().Values(); foreach (var prop in props) { if (!(prop is JObject) && !(prop is JArray)) { Console.WriteLine(prop.ToString()); } } //遍歷數組 var cardList = ((JArray)jobj["Cards"]); foreach (var card in cardList) { Console.WriteLine(card.ToString()); } //強類型讀取 Console.WriteLine(jobj.Value<int>("ID")); var p2 = jobj.ToString();
使用集合初始化語法:
JObject o = new JObject { {"CPU","Intel"}, {"Memory",2048}, { "Drives",new JArray { "DVD", "U盤" } } }; Console.WriteLine(o.ToString());
使用dynamic初始化:
dynamic address = new JObject(); address.Province = "beijing"; address.City = "beijing"; address.County = "zhongguo"; address.Villages = new JArray("aa", "bb"); Console.WriteLine(address.ToString());
使用JTokenWriter初始化:
JTokenWriter writer = new JTokenWriter(); writer.WriteStartObject(); writer.WritePropertyName("Title"); writer.WriteValue("aaaaaaa???"); writer.WritePropertyName("Detail"); writer.WriteStartArray(); writer.WriteValue("Yes"); writer.WriteValue("No"); writer.WriteValue("Unknown"); writer.WriteEndArray(); writer.WriteEndObject(); JObject o = (JObject)writer.Token; Console.WriteLine(o.ToString());
使用.NET值初始化:
JValue i = (JValue)JToken.FromObject(123); Console.WriteLine(i.Type); Console.WriteLine(i.ToString()); JValue s = (JValue)JToken.FromObject("GongHui"); Console.WriteLine(s.Type); Console.WriteLine(s.ToString()); Address address = new Address { City = "GuangZhou", Province = "GuangDong", County = "ShiQiao", Villages = new List<string> { "111", "222" } }; JObject o = (JObject)JToken.FromObject(address); Console.WriteLine(o.ToString());
遍歷JSON屬性:
/// <summary> /// 遍歷所以節點,替換其中某個節點的值 /// </summary> /// <param name="jobj">json數據</param> /// <param name="nodeName">節點名</param> /// <param name="value">新值</param> private static void JSON_SetChildNodes(ref JToken jobj, string nodeName, string value) { try { JToken result = jobj as JToken;//轉換為JToken JToken result2 = result.DeepClone();//復制一個返回值,由於遍歷的時候JToken的修改會終止遍歷,因此需要復制一個新的返回json //遍歷 var reader = result.CreateReader(); while (reader.Read()) { if (reader.Value != null) { if (reader.TokenType == JsonToken.String || reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float) { Regex reg = new Regex(@"" + nodeName + "$"); //SelectToken(Path)方法可查找某路徑下的節點,在Newtonsoft.Json 4.5 版本中不可使用正則匹配,在6.0版本中可用使用,會方便很多,6.0版本下替換值會更方便,這個需要特別注意的 if (reg.IsMatch(reader.Path)) { result2.SelectToken(reader.Path).Replace(value); } } } } jobj = result2; } catch (Exception ex) { } }
手動創建JObject:
var json = new JObject( new JProperty("status", result.Status.ToString()), new JProperty("results", new JObject(result.Entries.Select(pair => new JProperty(pair.Key, new JObject( new JProperty("status", pair.Value.Status.ToString()), new JProperty("description", pair.Value.Description), new JProperty("data", new JObject(pair.Value.Data.Select( p => new JProperty(p.Key, p.Value)))))))))); var str = json.ToString();
JToken合並:
需要引一個Nuget包:MassTransit
添加引用:using MassTransit.Courier.Serialization;
jObj.Merge(JObject.Parse(userTranslate.ValueJSON));
JToken查找:
jObject.SelectToken($".{path}");//根據路徑查找
Object轉JToken:
JToken.FromObject(object)
JToken轉Object:
jObj.ToObject<List<ApiOrderInfoSelectModel>>();
Merge方法:合並json
JObject o1 = JObject.Parse(@"{ 'FirstName': 'John', 'LastName': 'Smith', 'Enabled': false, 'Roles': [ 'User' ] }"); JObject o2 = JObject.Parse(@"{ 'Enabled': true, 'Roles': [ 'Admin' ] }"); o1.Merge(o2, new JsonMergeSettings { // union arrays together to avoid duplicates MergeArrayHandling = MergeArrayHandling.Union }); string json = o1.ToString(); // { // "FirstName": "John", // "LastName": "Smith", // "Enabled": true, // "Roles": [ // "User", // "Admin" // ] // }
參考: