Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Deserializing JSON to multiple types [duplicate]

Possible Duplicate:
Deserializing JSON into one of several C# subclasses

I have read-only access following JSON schema:

{ items: [{ type: "cat", catName: "tom" }, { type: "dog", dogName: "fluffy" }] } 

I would like to deserialize each of these to their respective type:

class Cat : Animal {     string Name { get; set; } } class Dog : Animal {     string Name { get; set; } } 

My only thought at this point is to deserialize them to a dynamic object, or Dictionary<string, object> and then construct these objects from there.

I may be missing something from one of the JSON frameworks out there....

What would your approach be? =]

like image 209
nullable Avatar asked Oct 11 '12 04:10

nullable


1 Answers

I think it's likely you'll need to deserialize the Json then construct the objects from there. Deserializing directly to Cat or Dog won't be possible as the deserializer won't know how to construct these objects specifically.

Edit: borrowing heavily from Deserializing heterogenous JSON array into covariant List<> using JSON.NET

Something like this would work:

interface IAnimal {     string Type { get; set; } }  class Cat : IAnimal {     public string CatName { get; set; }     public string Type { get; set; } }  class Dog : IAnimal {     public string DogName { get; set; }     public string Type { get; set; } }  class AnimalJson {     public IEnumerable<IAnimal> Items { get; set; } }  class Animal {     public string Type { get; set; }     public string Name { get; set; } }  class AnimalItemConverter : Newtonsoft.Json.Converters.CustomCreationConverter<IAnimal> {     public override IAnimal Create(Type objectType)     {         throw new NotImplementedException();     }      public IAnimal Create(Type objectType, JObject jObject)     {         var type = (string)jObject.Property("type");          switch (type)         {             case "cat":                 return new Cat();             case "dog":                 return new Dog();         }          throw new ApplicationException(String.Format("The animal type {0} is not supported!", type));     }      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)     {         // Load JObject from stream          JObject jObject = JObject.Load(reader);          // Create target object based on JObject          var target = Create(objectType, jObject);          // Populate the object properties          serializer.Populate(jObject.CreateReader(), target);          return target;     } }  string json = "{ items: [{ type: \"cat\", catName: \"tom\" }, { type: \"dog\", dogName: \"fluffy\" }] }"; object obj = JsonConvert.DeserializeObject<AnimalJson>(json, new AnimalItemConverter()); 
like image 58
nick_w Avatar answered Oct 07 '22 08:10

nick_w