Search code examples
c#json.netabstract-classjson-deserialization

JsonConvert deserialize an array of abstract classes


Let's say I have the following class structure (Building is an abstract class):

public class Street
{
    public string StreetName { get; set; }

    public Building[] Buildings { get; set; }
}

public abstract class Building
{
    public string Name { get; set; }
}

public class House : Building
{
    public int Floors { get; set; }
}

public class Flat : Building
{
    public int WhichFloor { get; set; }
}

I then create a street object with a few flats in the buildings array:

Flat f1 = new Flat { Name = "Flat 1", WhichFloor = 1 };
Flat f2 = new Flat { Name = "Flat 2", WhichFloor = 2 };

Street street = new Street
{
    StreetName = "Street Name",
    Buildings = new[] { f1, f2 }
};

Using JsonConvert I then Serialize the object:

var toJson = JsonConvert.SerializeObject(street);

Now I want to convert the json back to a street object:

var fromJson = JsonConvert.DeserializeObject<Street>(toJson);

This fails with the following error:

"Could not create an instance of type Building. Type is an interface or abstract class and cannot be instantiated. Path 'Buildings[0].WhichFloor'"

How can I tell the JsonConvert class that Buildings should be an array of flats?


Solution

  • As per @Evk's shared link, you should try setting TypeNameHandling to TypeNameHandling.Auto while serializing and deserializing:

    var toJson = JsonConvert.SerializeObject(street, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Auto
    });
    
    
    var fromJson = JsonConvert.DeserializeObject<Street>(toJson, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Auto
    });