使用JSON.NET反序列化任何内容 [英] Deserializing anything using JSON.NET
问题描述
我没有将JSON反序列化为已知类型或Dictionary对象的问题,但是如果我不知道输入将是什么情况呢?具体来说,我指的是接收代表一个平面或嵌套键值对集合的JSON字符串:
I have no issue deserializing JSON into known types or into Dictionary objects, but what about cases where I don't know what the input is going to be? Specifically I'm referring to receiving a JSON string that represents a flat or nested set of key-value pairs:
{
foo: 'bar',
baz: 42
}
或
{
foo:
{
bar: 42,
baz: ['foo', 'bar', 'baz']
}
}
但是,如果输入不是键值对,而是一个数组,或者是带有其他嵌套对象(包括数组)的对象数组,那么该怎么办?
But what about cases where the input isn't a key-value-pair, but rather an array, or, an array of objects with other nested objects (including arrays)?
[
{ foo: 'bar', baz: [ 1, 2, 3 ] },
{ foo: 'baz', bar: [ 4, 5, 6 ] }
]
我的目标是创建一个类,可以将上述任何一个反序列化为一个类,然后对其每个成员进行迭代.输入可以是任何结构,所以我不能认为数据会匹配我已经定义的任何类型.
My goal is to have a single class that I could deserialize any of the above into, and then iterate each of its members. The input could be of any structure, so I can't assume the data will come in matching any type I've already defined.
我一直无法找到一种方法来做到这一点.有人有指导吗?
I haven't been able to find a way to do this. Anyone have any guidance?
似乎很容易JToken.Parse JSON字符串;一个有用的下一步是迭代其成员并分别处理JArray和JObject.
Seems easy enough to JToken.Parse the JSON string; a helpful next step would be to iterate its members and handle JArray and JObject separately.
推荐答案
What you are describing already exists in Json.Net-- it is the LINQ-to-JSON API (JTokens). Below is an example of using it to parse arbitrary JSON and iterate through the members. Note that you need a recursive method to do it, since the JSON can be nested to any depth.
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main(string[] args)
{
string json1 = @"
{
""foo"": { ""bar"": 42, ""baz"": [ ""a"", ""b"", ""c"" ] }
}";
DeserializeAndDump(json1, "example 1");
string json2 = @"
[
{ ""foo"": ""bar"", ""baz"": [ 1, 2, 3 ] },
{ ""foo"": ""baz"", ""bar"": [ 4, 5, 6 ] }
]";
DeserializeAndDump(json2, "example 2");
}
public static void DeserializeAndDump(string json, string label)
{
Console.WriteLine("---- " + label + " ----");
JToken token = JToken.Parse(json);
DumpJToken(token);
Console.WriteLine();
}
public static void DumpJToken(JToken token, string indent = "")
{
if (token.Type == JTokenType.Object)
{
Console.WriteLine(indent + "begin object");
foreach (JProperty prop in token.Children<JProperty>())
{
Console.WriteLine(indent + " " + prop.Name + ":");
DumpJToken(prop.Value, indent + " ");
}
Console.WriteLine(indent + "end object");
}
else if (token.Type == JTokenType.Array)
{
Console.WriteLine(indent + "begin array");
foreach (JToken child in token.Children())
{
DumpJToken(child, indent + " ");
}
Console.WriteLine(indent + "end array");
}
else
{
Console.WriteLine(indent + token.ToString() + " (" + token.Type.ToString() + ")");
}
}
}
以下是上面的输出:
---- example 1 ----
begin object
foo:
begin object
bar:
42 (Integer)
baz:
begin array
a (String)
b (String)
c (String)
end array
end object
end object
---- example 2 ----
begin array
begin object
foo:
bar (String)
baz:
begin array
1 (Integer)
2 (Integer)
3 (Integer)
end array
end object
begin object
foo:
baz (String)
bar:
begin array
4 (Integer)
5 (Integer)
6 (Integer)
end array
end object
end array
提琴: https://dotnetfiddle.net/dfk0sj
这篇关于使用JSON.NET反序列化任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!