I am reading a json file that contains array of pets. Then I am creating list of PetBase
that contains these pets. I am not sure how to write proper serializer for this. The customSerializer should init the proper child class and return that class. The json contains a field called type
that tells us what kind of pet we got currently..so we can initialize the proper object type.
This is the doc that is close to what I want to do but not able to get it done. https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm
This is the Newtonsoft 'ToObject' method I am using and unable to find example of https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_ToObject__1_1.htm
JObject o1 = JObject.Parse(File.ReadAllText(@"path"));
CustomSerializer customSerializer = new CustomSerializer();
JsonSerializer jSerializer = new JsonSerializer();
jSerializer.Converters.Add(customSerializer);
//this following line errors out in CustomSerializer Class
var listOfPets = o1["allPets"].ToObject<List<PetBase>>(jSerializer );
Here are the sample classes:
public class PetBase {
string Name;
string Age;
}
public class Dog:PetBase
{
public string bark{get;set;}
public string Bark() {
return bark;
}
}
public class Cat : PetBase
{
public int lives{get;set;}
public int HowManyLives() {
return lives;
}
}
Sample Json
{
"allPets": [
{
"type": "cat",
"lives": 10
},
{
"type": "dog",
"bark": "woof"
}
]
}
Custom Serializer
public class CustomSerializer: JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//program fails here saying
//Newtonsoft.Json.JsonReaderException: 'Error reading JObject from JsonReader.
//Current JsonReader item is not an object: StartArray.
JObject jsonObject = JObject.Load(reader); <------------------
var properties = jsonObject.Properties().ToList();
//not tested bellow..but this is the idea...
if(properties["type"]=="dog")
return new Dog():
if(properties["type"]=="cat")
return new Cat():
}
}