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

时间:2018-06-18 23:31:54

标签: c# .net json serialization json.net

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

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");

1 个答案:

答案 0 :(得分:0)

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

如果您知道自己接收的类型,则应直接反序列化为该类型。

无论如何,你应该考虑你的对象类型层次结构,以及它是否需要按照它的方式进行结构化。