将JSON反序列化为多个继承的类

时间:2017-03-17 12:56:05

标签: c# json reflection azure-cosmosdb

当我从DocumentDB序列化我的JSON对象时,我的Control没有反序列化为OptionsControl Options属性。

我有以下课程Control

public class Control : IControl
{
    public Guid Id { get; set; }

    public virtual Enums.ControlType Type { get; set; }

    public string PropertyName { get; set; }

    public string ControlCssClass { get; set; }

    public string Description { get; set; }
}

我还有OptionsControl,它继承自Control

public class OptionsControl : Control
{
    public IDictionary<string, string> Options;
}

我还有ClickableControl

public class ClickableControl : Control
{
    public string Url { get; set; }
    public string UrlTarget { get; set; }
}

我使用Azure中的文档资源管理器将这个JSON放在document的DocumentDB collection中:

Rows:
[
    {
        Controls:
        [
            {
              "PropertyName": "Relationship",
              "ControlCssClass": "",
              "Description": "",
              "Type": 3,
              "Options": [
                  {
                    "Key": "Spouse",
                    "Value": "Spouse"
                  },
                  {
                    "Key": "Child",
                    "Value": "Child"
                  },
                  {
                    "Key": "Step-child",
                    "Value": "Step-child"
                  }
              ],
           }
        ]
    }
]

当我从DocumentDB中提取数据时,我尝试将其序列化到我的Row类中:

public class Row
{
    public IList<Control> Controls { get; set; }
}

我需要能够放置任何类型的&#34; Control&#34;在我的DocDB控制列表中,让C#反序列化,将其列回正确的Control类(基础Control类,或OptionsControl或{{1}等衍生类别之一})。

问题是因为我反序列化为ClickableControl,除了Control之外,我获得了控件上的所有属性。或者,如果我尝试反序列化具有OptionsUrl的那个,我只获取基本Control属性而不是URL属性。我认为C#会处理将反序列化的对象转换为OptionsControl或ClickableControl,但我想这是不正确的?我需要做什么才能使DocumentDB中的JSON对象正确序列化并转换为UrlTarget(具有Options属性)而不仅仅是基本控件?

1 个答案:

答案 0 :(得分:3)

您可以尝试使用Json.NET自行序列化对象,然后将序列化内容发布到DocumentDb中。然后,当您需要数据时,将其作为json字符串读回并再次使用Json.NET进行反序列化。 Json.NET可以处理继承,因此您只需将其配置为了解您的类型层次结构。使用TypeNameHandling设置:

this

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
};