1

I am using Xamarin forms and fetching a list of JSON objects, which are of multiple Types. E.g.

class BaseClass
{
    public int Id;
}

class ClassA: BaseClass
{
    public string Name;
}

class ClassB: BaseClass
{
    public DateTime DateOfBirth;
}

and so on..

When I fetch such objects (ClassA, ClassB, ...), I use the following line to deserialize them into the BaseClass

var response = await RestClient.PostTaskAsync<List<BaseClass>>(request);

And latter try to cast them into ClassA or ClassB, only to get null for all the BaseClass objects. I simply expect a List<BaseClass> containing ClassA, ClassB... objects.

What am I missing here? Is there a setting/configuration for the Serializer , where I could pass the specific classes to get the specifically serialized?

bit
  • 4,407
  • 1
  • 28
  • 50

2 Answers2

0

You are telling it to deserialize the response to a list of BaseClass objects... that's exactly what it's returning to you. I'm not entirely sure how you would do a conditional deserialization. An approach I have used in the past is to have a PostTaskResponse object that defines all the possible properties you would have, then cast those to your expected result.

Daniel Gary
  • 507
  • 4
  • 10
0

I was able to accomplish this with a custom JsonConverter

public class CustomConverter : JsonConverter {
    public override bool CanConvert(Type objectType) {
        return (objectType == typeof(BaseClass));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        JObject jo = JObject.Load(reader);

        if (jo["identifyingField"].Value<string>() == "ExpectedValue")
            return jo.ToObject<ConcreteClass>(serializer);

        if (jo["identifyingField"].Value<string>() == "ExpentedValue2")
            return jo.ToObject<ConcreteClass2>(serializer);

        return null;
    }

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

Luckily my objects had an identifying field in them which makes things easier...

If all of your concrete classes have unique fields to them, you can simply check jo["identifyingField"] != null

json.net has key method?

And to use your new CustomConverter...

var content = await httpResponse.Content.ReadAsStringAsync();    
JsonConverter[] converters = { new CustomConverter() };
var result = JsonConvert.DeserializeObject<SomeObject>(content, new JsonSerializerSettings { Converters = converters});
Gunnar
  • 78
  • 1
  • 7
  • So was I, although it was a slightly different implementation since the `ToObject<>()` didn't really work for me. Thanks. – bit Mar 08 '18 at 07:40