0

Lets assume i have base class and 2 derived classes:

pulic class BaseHumanClass {
    public int Id { get; set; }
}

public class Adult : BaseHumanClass {
    public string Name { get; set;}
}

public class Child : BaseHumanClass {
    public int Age { get; set; }
}

And i'm getting list from api, something like this:

[{ Id: 1, Name: "Dave" }, { Id: 2, Age: 64 }]

How can i use jsonconvert.DeserializeObject to get list with the right derived classes corresponded to the parameters?

Thx

mudale
  • 78
  • 7

2 Answers2

2

you will need a custom json converter like this

List<BaseHumanClass> list = JsonConvert.DeserializeObject<List<BaseHumanClass>>(json, 
                                                   new SelectClassJsonConverter());

 //test
string type = list[1].GetType().ToString(); // Child

public class SelectClassJsonConverter : Newtonsoft.Json.JsonConverter<List<BaseHumanClass>>
{
    public override List<BaseHumanClass> ReadJson(JsonReader reader, Type objectType, List<BaseHumanClass> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        return JArray.Load(reader).Select(item => item["Age"] == null
                                   ? (BaseHumanClass)item.ToObject<Adult>()
                                   : (BaseHumanClass)item.ToObject<Child>())
                                   .ToList();
    }

    public override void WriteJson(JsonWriter writer, List<BaseHumanClass> value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
Serge
  • 40,935
  • 4
  • 18
  • 45
0

You can use nuget package JsonSubTypes, here is a running sample (https://dotnetfiddle.net/YlUGp5):

using System;
using JsonSubTypes;
using Newtonsoft.Json;
using System.Collections.Generic;

[JsonConverter(typeof(JsonSubtypes))]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Adult), "Name")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(Child), "Age")]
public class BaseHumanClass {
    public int Id { get; set; }
}

public class Adult : BaseHumanClass {
    public string Name { get; set;}
}

public class Child : BaseHumanClass {
    public int Age { get; set; }
}
                    
public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        
        string json = "[{\"Id\":1,\"Name\":\"Dave\"},{\"Id\":2,\"Age\":64}]";


        var humans = JsonConvert.DeserializeObject<ICollection<BaseHumanClass>>(json);
        
        foreach (var human in humans) {
            Console.WriteLine(human.GetType() + ": " + human.Id);
        }
    }
}

See also https://manuc66.github.io/JsonSubTypes/ for usage documentation

manuc66
  • 2,701
  • 29
  • 28