Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialize JSON to subclasses

Tags:

c#

json.net

I have 3 classes:

class Person {
    public bool IsFemale { get; set; }
}

class Female : Person {
    public string FemaleSpecificProperty { get; set; }
}

class Male: Person { 
    public string MaleSpecificProperty { get; set; }
}

How can I deserialize given JSON string into specific instances (Female or Male) based on the value of Person.IsFemale property? (upfront I dont know which exact type has been used and that property is the only indication)

I looked at employing CustomCreationConverter<T> but couldn't figure out how to make it work here.

like image 392
Maxim Avatar asked Jul 06 '13 06:07

Maxim


1 Answers

Here is converter for your person class. It gets IsFemale field value, and based on it creates Female or Male person, which is populated by serializer:

public class PersonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Person).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);
        var isFemale = (bool)jObject["IsFemale"];
        Person target = isFemale ? (Person)new Female() : new Male();
        serializer.Populate(jObject.CreateReader(), target);
        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, 
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Usage:

List<Person> people = new List<Person>
{
    new Male { IsFemale = false, MaleSpecificProperty = "Y" },
    new Male { IsFemale = false, MaleSpecificProperty = "Y" },
    new Female { IsFemale = true, FemaleSpecificProperty = "X" }
};

string json = JsonConvert.SerializeObject(people);
var result = 
     JsonConvert.DeserializeObject<List<Person>>(json, new PersonConverter());

Also take a look on question suggested by alex: How to implement custom JsonConverter

like image 128
Sergey Berezovskiy Avatar answered Sep 20 '22 14:09

Sergey Berezovskiy