65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JSON.NET 的动态类型

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (6投票s)

2013年8月4日

CPOL

2分钟阅读

viewsIcon

46290

downloadIcon

571

使用 JSON.NET 反序列化动态类型对象的集合。

引言   

本文展示了如何使用 JSON.NET 将 JSON 反序列化为动态类型对象的集合。

背景  

对于刚开始使用 JSON.NET 的人来说,一个常见的问题是:如何反序列化一个对象集合,我们只知道其基本类型,而实际类型需要在转换过程中,根据 JSON 数据来确定?

这是一个关于 JSON.NET 的基本问题,我打算在这里以最简单的方式来解答。

让我们考虑两种你可能会遇到的典型 JSON 示例:

  • 将 JSON 数组反序列化为 List 类型
  • 将 JSON 对象列表反序列化为 Dictionary 类型

我们首先声明期望数据的类:

public class TestBase
{
}

public class TestA : TestBase
{
    public string text;
}

public class TestB : TestBase
{
    public DateTime date;
} 

对于 List<TestBase> 类型的列表,你可以使用如下所示的 JSON:

[
    {
    type: "testA",
    text: "something"
    },
    {
    type: "testB",
    date: "02/03/2010"
    }
]

对于 Dictionary<int, TestBase> 类型的字典,你可能使用如下 JSON:

{
    1:
    {
    type: "testA",
    text: "something"
    },
    2:
    {
    type: "testB",
    date: "02/03/2010"
    }
}

在上述两个 JSON 示例中,我们添加了属性 type 来告诉我们哪个对象类型可以包含数据。我们只需要一种方法将它传递给 JSON 反序列化器,以便正确实例化类型。下一章将解释如何做到这一点。

使用代码 

我们假设你已经有一个使用 JSON.NET 的项目,因为如果没有,这个技巧对你来说毫无意义。

为了将 JSON 转换为上述 ListDictionary 类型,请使用如下代码:

JsonVirtualConverter<TestBase> jvc = new JsonVirtualConverter<TestBase>("type", t =>
{
    switch (t)
    {
        case "testA":
            return new TestA();
        case "testB":
            return new TestB();
        default:
            return null;
    }
});

// Reading JSON from two files:
string list = File.ReadAllText("../../JSON/ListData.json");
string dict = File.ReadAllText("../../JSON/DictData.json");

// Now we can read and transform all data automatically:
List<TestBase> a = JsonConvert.DeserializeObject<List<TestBase>>(list, jvc);
Dictionary<int, TestBase> b = JsonConvert.DeserializeObject<Dictionary<int, TestBase>>(dict, jvc);

在上述代码中,我们设置了实例化对象,以便根据属性 type 创建正确的对象类型,然后让 JSON.NET 处理剩下的事情。

对于这两个转换,我们传递了一个 JsonVirtualConverter 的实例,这是一个非常简单的类,附带在本文章中,仅仅是为了解决本文描述的精确问题。

关注点   

目前,正在参与一个 Web 项目,涉及高级 JSON 操作。

此外,通过发布这个技巧,我试图引起 JSON.NET 作者 James Newton-King 的注意,说服他将这个简单的类 JsonVirtualConverter 包含在 JSON.NET 的下一个版本中。他似乎很难联系到 :)

历史

  • 2013年8月4日 - 初始草稿

© . All rights reserved.