【问题标题】:Using JSON.NET to deserialize a list whose type is an interface使用 JSON.NET 反序列化类型为接口的列表
【发布时间】:2012-12-09 18:37:39
【问题描述】:

我有一个“包装器”类,用于包含不同类型事件的列表。因此,列表本身使用通用的“AnEvent”接口而不是具体类型。

public class EventLog
{
    [JsonProperty()]
    private List<AnEvent> events;

    // note that the list is private and has no getter/setter
}

界面如下:

//public enum EventTypes { EventA, EventB };

public interface AnEvent
{
    EventTypes EventType
    {
        get;
        set;
    }

    // some other properties...
}

最后但同样重要的是,具体的事件类型可能如下所示:

public class ConcreteEventA : AnEvent
{
    private EventTypes eventType = EventTypes.EventA;

    public EventTypes EventType
    {
        get { return eventType; }
        set { eventType = value; }
    }

     // ...
}


public class ConcreteEventB : Event
{
    // ....
}

如您所见,这里关于事件类型的信息有点多余(有类本身的类型,例如ConcreteEventA,类内部还有一个叫做EventType(enum)的属性)。

EventLog 对象的序列化工作正常并返回事件的 JSON 列表。事件的类型表示为:"EventType": 0(它是枚举的“EventA”)。

但我无法将 JSON 反序列化回 EventLog 实例(“类型是接口或抽象类,无法实例化”)。当然,绝对清楚解串器无法确定列表中每个事件所需的类型。但是,由于 EventType 属性(在本例中为 0 或 1),我得到了类型的信息,我想知道如何使用这些信息正确地反序列化整个事情。

谢谢。

【问题讨论】:

  • 有时存在一些属性,这些属性为反序列化器提供了有关真实类类型的信息。然后可以反序列化接口。因为我不知道你的解串器,所以我不能告诉你这些是哪一个
  • 我还是不明白你这个界面的目的是什么。在这种情况下为一种类型的事件设置几个构造函数不是更聪明吗?

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


【解决方案1】:

JsonConverter你能在这方面提供帮助吗?但是您需要在进行序列化时输入类型名称。更多信息请看问题using-json-net-converters-to-deserialize-properties

【讨论】:

    【解决方案2】:

    嗯,它不是 JSON.Net,但使用 System.Web.Script.Serialization.JavaScriptSerializer,您可以使用 SimpleTypeResolver 将派生类型映射到接口。

    使用 JSON.Net,这似乎可以通过 IContractResolver 来实现,它使您可以使用自定义行为来处理序列化和反序列化级别。

    似乎这两种方法都需要在序列化过程中将某些东西(例如指示类型的额外属性)插入到 JSON 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多