当前位置: 首页 > 工具软件 > jtoken > 使用案例 >

Newtonsoft.Json笔记 -JToken、JObject、JArray详解

长孙高远
2023-12-01

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

 类似资料: