Json.Net不保存$ type信息

时间:2017-04-14 17:31:50

标签: c# json serialization json.net

当我序列化Page对象时,Json.Net在序列化它们时没有将$ type属性添加到我的控件(它们在IList中)。我已经尝试将以下代码添加到我的类构造函数和我的WebAPI Startup中,但是Json.Net仍然没有将$ type信息添加到它序列化的Control

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

出于测试目的,我在JSON代码中将$type属性添加到Control中,并且Json.Net能够反序列化对象,但它仍然没有序列化正确。以下是我的课程设置方式。

public class Page {
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    public IList<Control> Controls { get; set; }
}

这是Control类:

public class Control : ControlBase
{
    public override Enums.CsControlType CsControlType { get { return Enums.CsControlType.Base; } }
}

这是ControlBase抽象类:

public abstract class ControlBase
{
    public Guid Id { get; set; }

    public virtual Enums.CsControlType CsControlType { get; }

    public Enums.ControlType Type { get; set; }

    public string PropertyName { get; set; }

    public IList<int> Width { get; set; }

    public string FriendlyName { get; set; }

    public string Description { get; set; }
}

以下是从Control:

派生的OptionsControl
public class OptionsControl : Control
{
    public override Enums.CsControlType CsControlType { get { return Enums.CsControlType.OptionsControl; } }

    public IDictionary<string, string> Options;
}

这就是JSON的出现方式:

"Pages": [
    {
      "Id": "00000000-0000-0000-0000-000000000000",
      "CustomerId": "00000000-0000-0000-0000-000000000000",
      "Controls": [
        {
          "Options": {
            "TN": "TN"
          },
          "CsControlType": 4,
          "Id": "00000000-0000-0000-0000-000000000000",
          "Type": 4,
          "PropertyName": "addresses[0].state",
          "Width": [
            2,
            2,
            6
          ],
          "FriendlyName": "State",
          "Description": null
        }
      ]
    }
]

如您所见,Json.Net未将$type属性添加到JSON对象。问题是,有时我需要Json.Net给我一个基础Control对象,但有时我需要它给我一个OptionsControl对象的实例(继承自Control)。为什么Json.Net没有将$ type属性添加到我的控件中?

1 个答案:

答案 0 :(得分:1)

您可以将[JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]添加到public IList<Control> Controls { get; set; }属性,以强制为列表中的每个项目发送类型信息,而不是修改框架使用的全局设置:

public class Page
{
    public Guid Id { get; set; }
    public Guid CustomerId { get; set; }
    [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
    public IList<Control> Controls { get; set; }
}

示例fiddle

您可以考虑使用自定义序列化活页夹清理类型信息,原因如here所述。