.NET Deserializing JSON для нескольких типов - программирование
Подтвердить что ты не робот

.NET Deserializing JSON для нескольких типов

Возможный дубликат:
десериализация JSON в один из нескольких подклассов С#

У меня есть доступ только для чтения после схемы 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....

Каким будет ваш подход? =]

4b9b3361

Ответ 1

Я думаю, что вам, вероятно, понадобится десериализовать Json, а затем построить объекты оттуда. Удаление десериализации непосредственно на Cat или Dog не будет возможным, поскольку десериализатор не будет знать, как сконструировать эти объекты.

Изменить: сильно заимствовать из десериализацию гетерогенного массива JSON в ковариантный список < gt; используя 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());