c# - 使用 JSON.NET 反序列化任何内容

标签 c# json.net

我可以将 JSON 反序列化为已知类型或 Dictionary 对象,但是如果我不知道输入是什么,该怎么办?具体来说,我指的是接收表示一组平面或嵌套键值对的 JSON 字符串:

{ 
  foo: 'bar',
  baz: 42
}

{
  foo: 
  {
    bar: 42,
    baz: ['foo', 'bar', 'baz']
  }
}

但是如果输入不是键值对,而是一个数组,或者是一个包含其他嵌套对象(包括数组)的对象数组,情况又如何呢?

[
  { foo: 'bar', baz: [ 1, 2, 3 ] },
  { foo: 'baz', bar: [ 4, 5, 6 ] }
]

我的目标是拥有一个可以将上述任何内容反序列化到的单个类,然后迭代其每个成员。输入可以是任何结构,因此我不能假设数据将与我已经定义的任何类型匹配。

我还没有找到一种方法来做到这一点。有人有指导吗?

编辑:

JToken.Parse JSON 字符串似乎很容易;下一步有用的步骤是迭代其成员并分别处理 JArray 和 JObject。

最佳答案

您所描述的内容已存在于 Json.Net 中 - 它是 LINQ-to-JSON API (JToken)。下面是使用它解析任意 JSON 并迭代成员的示例。请注意,您需要一个递归方法来执行此操作,因为 JSON 可以嵌套到任何深度。

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

fiddle :https://dotnetfiddle.net/dfk0sj

关于c# - 使用 JSON.NET 反序列化任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39962368/

相关文章:

javascript - 从 Unity webGL 应用程序导出网格并将其与 AR.js 制作者关联

c# - 具有泛型类型的接口(interface) API 调用

c# - 无法反序列化包含 $ref 键的 JSON

c# - 如何以编程方式从动态 JObject 获取属性

c# - 从 PRISM 中的区域获取 HostControl

c# - Ninject 的 WCF 无参数构造函数错误

c# - 如何使用 System.Text.Json 将 Newtonsoft JToken 序列化为 JSON?

c# - Json.net 在 MVC4 中使用循环引用反序列化 json

除英语之外的 C# WritePrivateProfileString() 值

c# - 像数字单元格一样订购数据网格图像单元格?可能的?