【问题标题】:.NET Deserializing JSON to multiple types [duplicate].NET 将 JSON 反序列化为多种类型
【发布时间】:2012-10-01 16:32:48
【问题描述】:

可能重复:
Deserializing JSON into one of several C# subclasses

我具有以下 JSON 架构的只读访问权限:

{ items: [{ type: "cat", catName: "tom" }, { type: "dog", dogName: "fluffy" }] }

我想将这些反序列化为各自的类型:

class Cat : Animal {
    string Name { get; set; }
}
class Dog : Animal {
    string Name { get; set; }
}

此时我唯一的想法是将它们反序列化为dynamic 对象或Dictionary<string, object>,然后从那里构造这些对象。

我可能在其中一个 JSON 框架中遗漏了一些东西......

您的方法是什么? =]

【问题讨论】:

  • 这里接受的答案可以说比链接问题的答案要好得多。

标签: .net json deserialization


【解决方案1】:

我认为您可能需要反序列化 Json,然后从那里构造对象。直接反序列化为CatDog 是不可能的,因为反序列化器不知道如何专门构造这些对象。

编辑:大量借鉴Deserializing heterogenous JSON array into covariant List<> using JSON.NET

这样的事情会起作用:

interface IAnimal
{
    string Type { get; set; }
}

class Cat : IAnimal
{
    public string CatName { get; set; }
    public string Type { get; set; }
}

class Dog : IAnimal
{
    public string DogName { get; set; }
    public string Type { get; set; }
}

class AnimalJson
{
    public IEnumerable<IAnimal> Items { get; set; }
}

class Animal
{
    public string Type { get; set; }
    public string Name { get; set; }
}

class AnimalItemConverter : Newtonsoft.Json.Converters.CustomCreationConverter<IAnimal>
{
    public override IAnimal Create(Type objectType)
    {
        throw new NotImplementedException();
    }

    public IAnimal Create(Type objectType, JObject jObject)
    {
        var type = (string)jObject.Property("type");

        switch (type)
        {
            case "cat":
                return new Cat();
            case "dog":
                return new Dog();
        }

        throw new ApplicationException(String.Format("The animal type {0} is not supported!", type));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Load JObject from stream 
        JObject jObject = JObject.Load(reader);

        // Create target object based on JObject 
        var target = Create(objectType, jObject);

        // Populate the object properties 
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }
}

string json = "{ items: [{ type: \"cat\", catName: \"tom\" }, { type: \"dog\", dogName: \"fluffy\" }] }";
object obj = JsonConvert.DeserializeObject<AnimalJson>(json, new AnimalItemConverter());

【讨论】:

  • 谢谢。我同意。我喜欢这个例子,但不幸的是所有属性都没有共享。我已经更新了我的示例以反映这一点。
  • 感谢您的回答。我将我的问题标记为重复,但我认为这是一个更好的答案。
  • 回答得很好。感谢您的编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-20
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多