在反序列化期间创建子类型



我得到了以下JSON文档:

{
    "Title": "jkdjdjd",
    "Description": "dkfkkdd",
    "Actions": [{
                    "ActionType": "Email",
                    "Subject": "Bkdfkdk",
                    "Body": "kddkdkkd"
                }, {
                    "ActionType": "SMS",
                    "PhoneNumber": "+46333333"
                }
    ]
}

我的课程如下所示:

public class Trigger
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Action> Actions { get; set; }
}

public class Action
{
    public string ActionType { get; set; }
}
public class EmailAction : Action
{
    public string Subject { get; set; }
    public string Body { get; set; }
}
public class SmsAction : Action
{
    public string PhoneNumber { get; set; }
}

所以我基本上想要的是 JSON.NET 根据"ActionType"中的名称选择子类的类型。我知道 JSON.NET 支持一个可用于识别子类的特殊字段。但我宁愿让友好名称控制要生成的类。

我已经发现我应该使用CustomCreationConverter<Action>进行选择。但是我不知道如何在不搞砸实际反序列化的情况下读取该字段。

如果有帮助,我可以改用以下布局:

public class Action
{
    public string ActionType { get; set; }
    public ActionData Data { get; set; }
}
public ActionData
{
}
public class EmailData : ActionData
{
    public string Subject { get; set; }
    public string Body { get; set; }
}
public class SmsData : ActionData
{
    public string PhoneNumber { get; set; }
}

即 JSON 将是:

{
    "Title": "jkdjdjd",
    "Description": "dkfkkdd",
    "Actions": [{
                    "ActionType": "Email",
                    "Data": {
                        "Subject": "Bkdfkdk",
                        "Body": "kddkdkkd"
                    }
                }, {
                    "ActionType": "SMS",
                    "Data": {
                        "PhoneNumber": "+46333333"
                    }
                }
    ]
}

如果您不为在 JSON 中包含 type 属性而烦恼,您可以使用 JsonSerializer TypeNameHandling = TypeNameHandling.Auto 的设置。

否则,您可以创建自定义JsonConverter并将其添加到序列化期间使用的转换器列表中。这篇文章中有一个很好的例子,对我来说效果很好:

http://dotnetbyexample.blogspot.co.uk/2012/02/json-deserialization-with-jsonnet-class.html

编辑:

这不能像预期的那样对您有用吗?您是否尝试过将Action基类抽象化?

您在创建转换器方面尝试了什么?它究竟是如何不起作用的 - 你能提供一些细节吗?

public class JsonActionConverter : JsonCreationConverter<Action>
  {
    protected override Action Create(Type objectType, JObject jsonObject)
    {
      var typeName = jsonObject["ActionType"].ToString();
      switch(typeName)
      {
        case "Email":
          return new EmailAction();
        case "SMS":
          return new SMSAction();
        default: return null;
      }
    }
  }

相关内容

  • 没有找到相关文章

最新更新