.net - 具有多态对象的数组的 JSON 序列化

标签 .net json serialization polymorphism

是否可以使用.NET标准JavascriptSerializer/JsonDataContractSerializer或外部解析器,使用包含对象类型的包装器方法序列化对象数组?

例如,要从列表生成此 JSON:

[{ 'dog': { ...dog properties... } },
 { 'cat': { ...cat properties... } }]

而不是典型的:

[{ ...dog properties... },
 { ...cat properties... }]

这可以在 Java 中使用 Jackson 使用 JsonTypeInfo.As.WRAPPER_OBJECT 属性来实现。

最佳答案

Json.NET对此有一个巧妙的解决方案。有一个设置可以智能地添加类型信息 - 像这样声明它:

new JsonSerializer { TypeNameHandling = TypeNameHandling.Auto };

这将确定是否需要类型嵌入并在必要时添加它。假设我有以下类(class):

public class Message
{
    public object Body { get; set; }
}

public class Person
{
    public string Name { get; set; }
}

public class Manager : Person
{

}

public class Department
{
    private List<Person> _employees = new List<Person>();
    public List<Person> Employees { get { return _employees; } }
}

请注意,消息正文是对象类型,并且 Manager 是 Person 的子类。如果我使用具有单个经理的部门机构序列化消息,我会得到以下信息:

{
    "Body":
    {
        "$type":"Department, MyAssembly",
        "Employees":[
            {
                "$type":"Manager, MyAssembly",
                "Name":"Tim"
            }]
    }
}

注意它是如何添加 $type 属性来描述 Department 和 Manager 类型的。如果我现在将一个人添加到员工列表中并将消息正文更改为部门类型,如下所示:

public class Message
{
    public Department Body { get; set; }
}

那么不再需要 Body 类型注释,并且新的 Person 不会被注释 - 缺少注释假定元素实例是声明的数组类型。序列化后的格式变为:

{
    "Body":
    {
        "Employees":[
            {
                "$type":"Manager, MyAssembly",
                "Name":"Tim"
            },
            {
                "Name":"James"
            }]
    }
}

这是一种有效的方法 - 仅在需要时添加类型注释。虽然这是特定于 .NET 的,但该方法足够简单,可以处理其他平台上的反序列化器/消息类型应该相当容易地扩展来处理此问题。

不过,我对在公共(public) API 中使用它持谨慎态度,因为它是非标准的。在这种情况下,您需要避免多态性,并使版本控制和类型信息成为消息中非常明确的属性。

关于.net - 具有多态对象的数组的 JSON 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5186973/

相关文章:

c - 用 C 序列化包

.net - 如何将信号连接到.NET中的复杂电路?

javascript - 为什么 AngularJS "$http.get().then(...)"适用于纯文本文件,但不适用于 JSON 文件?

ios - iOS上传JSON文档时需要检测app无法连接服务器的情况

json - 来自 JSON 调用的 NodeJS 奇怪响应

java - java中默认和生成的串行版本uid有什么区别?

c# - Unity 5 游戏对象序列化

c# - 类中通用项目的通用集合?

.net - 对于提供线程安全添加、删除、迭代集合到各种对象的包装器来说,最好的名称是什么?

.net - 如何从函数返回格式化的字符串?