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

3
当我将JSON对象从DocumentDB序列化出来时,我的Control不能反序列化为具有Options属性的OptionsControl。
我有以下类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; }
}

我还有一个继承自ControlOptionsControl:

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 放入 DocumentDB 集合中的“文档”中:

documentcollection 是 Azure 的文档数据库中的术语。
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; }
}

我需要能够将任何类型的 "控件" 放入我的 DocDB 控件列表中,并让 C# 将该列表反序列化回适当的 Control 类(无论是基本的 Control 类,还是其中一个派生类,如 OptionsControlClickableControl)。

问题在于,由于我正在反序列化为 Control,因此我得到了 Control 上的所有属性,除了 Options。或者如果我尝试反序列化具有 UrlUrlTarget 的控件,则只会得到基本的 Control 属性,而不是 URL 属性。我以为 C# 会处理将反序列化对象转换为 OptionsControl 或 ClickableControl,但我想这是不正确的?我需要做什么才能使来自 DocumentDB 的 JSON 对象正确序列化并转换为 OptionsControl(具有 Options 属性),而不仅仅是基本的 Control?


然后反序列化一个 OptionsControl - user47589
我需要将其反序列化为多个Control类的派生类。 - undefined
我在过去处理过类似的问题,方法是在保存数据时包含实现类型。这样可以动态创建Control类型的实现,而无需在编译时指定它。 - undefined
@DannyBogers 我肯定可以添加控件类型。这就是我要做的,C#会处理剩下的事情吗?听起来太简单了!哈哈!但我会从那里开始。 - undefined
@Targaryen 这几乎就是这么简单,你可以通过完整的名称实例化一个 Type,如果你的序列化 API 支持的话,告诉它将你的控制反序列化为该特定类型。 - undefined
1个回答

6
您可以尝试使用Json.NET自行序列化对象,然后将序列化的内容发布到DocumentDb中。然后,当您需要数据时,将其读回作为json字符串,并再次使用Json.NET进行反序列化。 Json.NET可以处理继承,因此您只需配置它以了解您的类型层次结构即可。请使用TypeNameHandling设置: http://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
};

哇哦,好的。所以我首先需要使用Json.NET进行序列化。这太酷了!我会试一下的。 - undefined
1
如果其他方法都失败了,你可以使用DocumentDb的REST API,并自行发布序列化的JSON字符串内容。 - undefined
1
或者你可以尝试使用Json.NET的全局配置?不确定,但可能值得一试。查看这个链接: http://www.newtonsoft.com/json/help/html/DefaultSettings.htm - undefined
很高兴能帮忙 :) - undefined
一个有用的提示:为了使反序列化正常工作,您还需要将$type元数据字段添加到字符串中。如果没有添加,反序列化将无法正常工作。请查看此链接以获取更多详细信息:https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm - undefined
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接