11

I have a json structure that looks something like this:

"list":[
  {
    "type":"link",
    "href":"http://google.com"
  },
  {
    "type":"image",
    "src":"http://google.com/logo.png"
  },
  {
    "type":"text",
    "text":"some text here"
  },
]

I would like to deserialize this into a list of objects, where each object is a subclass of a base class. Each item in the list has different properties (href, src, text), so I can't use the same class for reach one. Instead I would like three subclasses of a general class. The type property of each item in the JSON list can be used to decide which subclass to use. So for example, I could have the following classes

public Item{
  public string type {get; set;}
}
public LinkItem : Item {
  public string href {get; set;}
}
public ImageItem : Item {
  public string src {get; set;}
}
public TextItem : Item {
  public string text {get; set;}
}

Is there any way to do this? Or is there a better way to deserialize a list of heterogeneous object types?

EDIT:

I am using json.net by the way

Marius
  • 57,995
  • 32
  • 132
  • 151
  • How about creating a class that has all the properties. Deserialize to get a list of that class instances. Then filter based on type and project the properties needed to create the specialized instances. Am assuming this is what you are currently doing, and are looking for an even better way? – Amith George Jul 11 '12 at 09:31
  • As the application grows the complexity of the individual items may increase, and it seems like a bad idea to have a base class with every possible property in it. What I'm considering is using an anonymous object, and then creating an instance later based on the type. – Marius Jul 11 '12 at 09:35
  • I didnt mean a base class. I was thinking more of intermediate dto class that has all possible options. From a list of dto objects, you can shape your required specialized objects. That way, your domain doesnt have to get muddled with serialization concerns. That said, you could use dynamic object? I didnt realize anonymous types could allow you to not define certain properties... As in the properties of the first deserialized anon object are not the same properties that the second deserialized anon object will have. – Amith George Jul 11 '12 at 09:43
  • possible duplicate of https://stackoverflow.com/questions/8030538/how-to-implement-custom-jsonconverter-in-json-net-to-deserialize-a-list-of-base/44662567 – manuc66 Jun 20 '17 at 22:29
  • There is a JsonConverter answer at https://stackoverflow.com/questions/12832306/net-deserializing-json-to-multiple-types – tymtam Dec 04 '20 at 23:20

1 Answers1

1

As @AmithGeorge suggested, you can use a dynamic object to dynamically parse your json object. You can use this great dynamic class for JSON by Shawn Weisfeld. Here is his blog explaining how he do it.

JavaScriptSerializer jss = new JavaScriptSerializer();
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });

dynamic glossaryEntry = jss.Deserialize(json, typeof(object)) as dynamic;

Console.WriteLine("glossaryEntry.glossary.title: " + glossaryEntry.glossary.title);
Console.WriteLine("glossaryEntry.glossary.GlossDiv.title: " + glossaryEntry.glossary.GlossDiv.title);
Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.ID: " + glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.ID);
Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para: " + glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para);
foreach (var also in glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso)
{
    Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso: " + also);
}
John Isaiah Carmona
  • 5,260
  • 10
  • 45
  • 79
  • The link is dead. Can you find and repost? - Thanks! –  Nov 03 '16 at 12:19
  • @DanVioletSagmiller I'm sorry, I think he already removed his repository. You can still follow the instructions on my second [link](http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx) though. – John Isaiah Carmona Nov 04 '16 at 02:46