【问题标题】:C#: Deserialize Json using InheritanceC#:使用继承反序列化 Json
【发布时间】:2015-12-28 20:34:06
【问题描述】:

我有以下代码创建一个对象并写入一个文件并从该文件中读取并尝试将其反序列化为同一个对象(代码可能看起来毫无意义,但我将大代码简化为一个小示例代码突出问题):

internal class Program
{
    private static void Main(string[] args)
    {
        string filePath = Path.Combine(@"C:\Users\user1", "TestFile.txt");

        TemplateA templateA = new TemplateA();
        templateA.objectsList = new List<TemplateX>();

        TemplateX templateX = new TemplateX();
        templateX.property1 = "Sample Value X1";

        TemplateY templateY = new TemplateY();
        templateY.property1 = "Sample value Y1";
        templateY.property2 = "Sample value Y2";

        templateA.objectsList.Add(templateX);
        templateA.objectsList.Add(templateY);

        string json = JsonConvert.SerializeObject(templateA, Formatting.Indented);
        File.WriteAllText(filePath, json);

        string jsonString = File.ReadAllText(filePath);
        TemplateA templateACopy = JsonConvert.DeserializeObject<TemplateA>(jsonString);
    }
}

internal class TemplateA
{
    [JsonProperty(PropertyName = "objectsList")]
    public List<TemplateX> objectsList;
}


internal class TemplateX
{
    [JsonProperty(PropertyName = "property1")]
    public string property1;
}

internal class TemplateY : TemplateX
{
    [JsonProperty(PropertyName = "property2")]
    public string property2;
}

当我将写入 TextFile.txt 的相同对象 templateA 读回 templateACopy 时,它丢失了属性 Y2(“样本值 Y2”)的信息。那就是 templateACopy 有:

这可以通过手动检查字符串是否具有类 TemplateY 的元素并使用适当的对象类型反序列化来纠正。但是有没有办法自动检测对象是继承类型并通过 Newtonsoft JsonConvert 的函数本身反序列化为适当的对象? (不知道 json 字符串是否有 TemplateX 或 TemplateY 类型的对象。这可以在运行时改变。)

【问题讨论】:

  • TemplateA 不知道或与TemplateY 有任何关系。您可以将 Y 对象添加到 objectsList,因为它们继承自 TemplateX
  • 您也可以启用TypeNameHandling.Auto,但它会生成非标准化的 json,并将类型嵌入到您的输出中。这意味着如果您更改类型名称,您的反序列化器将失败。如果这是可以接受的,这是另一种选择。 This second answer 讨论使用这种方法。
  • 所以,基本上你可以写一个自定义的JsonConverter,或者启用TypeNameHandling.Auto.
  • 您可以在 TemplateA 类中添加一个字段,该字段是实际类型。然后执行以下操作: TemplateA templateACopy = JsonConvert.DeserializeObject(jsonString);

标签: c# json inheritance serialization json-deserialization


【解决方案1】:

使用List&lt;baseType&gt; 的自定义设置,通过将 TypeNameHandling 指定给对象来序列化派生类型:

   var settings = new JsonSerializerSettings()
   {
      TypeNameHandling = TypeNameHandling.Objects
   };

   string json = JsonConvert.SerializeObject(templateA, settings);

   TemplateA templateACopy = 
            JsonConvert.DeserializeObject<TemplateA>(jsonString, settings);

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多