使用 JSON.NET 的动态类型






4.92/5 (6投票s)
使用 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 转换为上述 List
和 Dictionary
类型,请使用如下代码:
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日 - 初始草稿