Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserializing JSON into one of several C# subclasses

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

like image 619
Marius Avatar asked Jul 11 '12 09:07

Marius


1 Answers

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);
}
like image 79
John Isaiah Carmona Avatar answered Oct 22 '22 09:10

John Isaiah Carmona