C#:使用继承反序列化Json

时间:2015-12-28 20:34:06

标签: c# json inheritance serialization json-deserialization

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

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的相同对象模板A读回到templateACopy中时,它将丢失属性Y2的信息(&#34;样本值Y2和#34;)。那就是templateACopy有: templateACopy object contents

如果字符串具有Class TemplateY元素并使用适当的对象类型进行反序列化,则可以通过手动检查字符串来更正此问题。但有没有办法自动检测对象是一个继承类型,并通过Newtonsoft JsonConvert的函数反序列化到适当的对象? (事先不知道json字符串是否具有TemplateX或TemplateY类型的对象。这可以在运行时更改。)

1 个答案:

答案 0 :(得分:1)

使用List<baseType>的自定义设置,通过指定对象的TypeNameHandling来序列化派生类型:

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

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

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