在.NET 6中,微软加入了JSON Node,可以让我们动态编辑一个JSON文档,就像Newtonsoft.Json里的JToken一样,我们就可以更加灵活的操作JSON文档。
这次主要新增的API如下表:
我们可以使用JsonNode.Parse()方法将JSON转换成一个JsonNode对象,示例如下:
JsonNode jn = JsonNode.Parse("{\"age\":42}"); //方法一 int v = (int)jn["age"]; Debug.Assert(v == 42); //方法二 v = jn["age"].GetValue<int>(); Debug.Assert(v== 42);
我们可以通过AsObject将JsonToken转换为JsonObject,通过 AsArray将JArray转换为JsonArray,通过AsValue将JValue转换为JsonValue。对于JsonNode和JsonValue可以通过强制类型转成希望的类型,或者通过GetValue来转成类型,这类似于Newtonsoft.Json中的Value()方法,代码如下:
var jn = JsonNode.Parse("{\"age\":42}").AsObject(); //方法一 var jv = jn["age"].AsValue(); var v= (int)jv; Debug.Assert(v== 42); //方法二 v = jValue.GetValue<int>(); Debug.Assert(v== 42);
下面我们来看看修改JSON文档的例子:
var tobj= new {Name = "张三", Age = 42}; var jString= JsonSerializer.Serialize(tobj); var jNode= JsonNode.Parse(jString); if (jNode is JsonObject jObj) { jObj["Name"]?.GetValue<string>().Dump(); jObj["Age"]?.GetValue<int>().Dump(); jObj["Name"] = "李四"; jObj.ToJsonString().Dump(); }
在上面的代码中Dump方法是封装的扩展方法,它会把value值打印在控制台中。下面我们来看一下 JSON数组的例子:
var tArrayJsonString = JsonSerializer.Serialize(new[] { new {Name = "张三", Age = 30}, new {Name = "李四", Age = 20}, new {Name = "王五", Age = 10} }); jNode= JsonNode.Parse(tArrayJsonString); if (jNode is JsonArray jArray) { jArray.Select(item => $"{item["Name"]}, {item["Age"]}") .StringJoin(Environment.NewLine) .Dump(); }
对于复杂的组合JSON,我们可以按照如下代码进行处理:
var complexObj = new { Name = "VIP", Users = new[] { new {Name = "张三", Age = 60}, new {Name = "李四", Age = 70} } }; var jString = JsonSerializer.Serialize(complexObj); jString.Dump(); var jNode = JsonNode.Parse(jsonString); jNode?["Users"]?.AsArray().Select(item => $"{item["Name"]}, {item["Age"]}") .StringJoin(Environment.NewLine) .Dump();
需要注意的是现在有一点点JSON Path支持,JSON Path和XML Path一样,可以让我们高效的找到对应的JSON节点,但目前支持的并不好。JsonNode提供GetPath方法来获取当前Node对应的JSON Path,但是目前对于根据JSON Path查询的支持还是有问题。代码如下:
jNode["Users"][0]["Name"].GetPath().Dump(); JsonNode.Parse(@"{""Prop1"":1}")["Prop1"].GetPath().Dump();