Newtonsoft.Json筆記 -JToken、JObject、JArray詳解


在原來解析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"
            //   ]
            // }

 

參考:

https://blog.csdn.net/lovegonghui/article/details/50293629


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM