我得到了以下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;
}
}
}