是否有一种开箱即用的方法来反序列化 Json.Net 中的抽象类?

Posted

技术标签:

【中文标题】是否有一种开箱即用的方法来反序列化 Json.Net 中的抽象类?【英文标题】:Is there an out-of-box way to deserialize abstract classes in Json.Net? 【发布时间】:2018-11-27 20:21:03 【问题描述】:

问题:在我的数据模型中,我想定义一个具有抽象基类属性的类。

public class MyDataContract

    [JsonProperty("myFoo")]
    public Foo MyFoo  get; set; 

    [JsonProperty("correlationId")]
    public Guid Correlationid  get; set; 


public abstract class Foo

    [JsonProperty("id")]
    public int Id  get; set; 


public class Bar : Foo

    [JsonProperty("name")]
    public string Name  get; set; 


public class Baz : Foo

    [JsonProperty("time")]
    public DateTime Time  get; set; 

特别是,我想从消息队列中反序列化这些数据协定。但是JsonConcert.DeserializeObject<MyDataContract>(json) 会失败,因为MyFooabstract class。它无法弄清楚像

 
    myFoo: 
       id: 1293,
       name: 'Tom'
   ,
   correlationId: 'f70edc04-9465-4edd-9582-f066f62dab02'

是否有不涉及为我的数据合同滚动我自己的 JSON 转换器的解决方案?

或者做类似的事情

public class MyDataContract<T>
    where T : Foo

    [JsonProperty("myFoo")]
    public T MyFoo  get; set; 

    [JsonProperty("correlationId")]
    public Guid Correlationid  get; set; 

然后尝试喜欢

Foo foo = JsonConvert.DeserializeObject<MyDataContract<Foo>>(json);
if (foo != null)

    return foo;



Bar bar = JsonConvert.DeserializeObject<MyDataContract<Bar>>(json);
if (bar != null)

    return bar;


throw new InvalidOperationException("Uh-oh");

【问题讨论】:

TypeNameHandling Deserializing JSON to abstract class的可能重复 【参考方案1】:

如果您不知道网络(或其他系统边界)会出现什么特定类型,我认为您应该将所有属性添加到基类中,然后映射到更具体的类型(基于可用性/相关属性的非空状态)。您可以通过命名空间和访问修饰符来管理访问;取决于您的系统要求以及类型名称的清晰程度。

如果您确实知道收到的是什么类型,则应直接反序列化为该类型。

无论如何,您都应该考虑您的对象类型层次结构,以及它是否需要按照原来的方式构建。

【讨论】:

以上是关于是否有一种开箱即用的方法来反序列化 Json.Net 中的抽象类?的主要内容,如果未能解决你的问题,请参考以下文章

您如何在 .NET 中进行模拟?

在 Java 中实现请求限制的任何开箱即用的方法?

任何 .NET ORM 是不是支持开箱即用的本地化实体?

Windows Qt 二进制安装程序是不是支持开箱即用的 DBus?

开箱即用的分布式作业队列解决方案

如何通过 Sort 和 Pageable 使用 Spring data JPA 开箱即用地查询数据?