I am trying to deserialize some JSON for different subclasses using custom JsonConverter
I followed this almost to the point.
My abstract base class:
abstract class MenuItem { public String Title { get; set; } public String Contents { get; set; } public List<MenuItem> Submenus { get; set; } public String Source { get; set; } public String SourceType { get; set; } public abstract void DisplayContents(); }
And my resulting JsonConverter :
class MenuItemConverter : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(MenuItem).IsAssignableFrom(objectType); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject item = JObject.Load(reader); switch (item["SourceType"].Value<String>()) { case SourceType.File: return item.ToObject<Menu.FileMenu>(); case SourceType.Folder: return item.ToObject<Menu.FolderMenu>(); case SourceType.Json: return item.ToObject<Menu.JsonMenu>(); case SourceType.RestGet: return item.ToObject<Menu.RestMenu>(); case SourceType.Rss: return item.ToObject<Menu.RssMenu>(); case SourceType.Text: return item.ToObject<Menu.TextMenu>(); case SourceType.Url: return item.ToObject<Menu.UrlMenu>(); default: throw new ArgumentException("Invalid source type"); } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } }
SourceType is just a static class containing some string constants.
The JSON file is deserialized as follows:
JsonConvert.DeserializeObject<MenuItem>(File.ReadAllText(menuPath), new MenuItemConverter());
Now my problem is that whenever I run the code, I get the following error:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code Additional information: Could not create an instance of type ConsoleMenu.Model.MenuItem. Type is an interface or abstract class and cannot be instantiated. Path 'Submenus[0].Title', line 5, position 21.
The corresponding Json file is as follows:
{ "Title": "Main Menu", "Submenus": [ { "Title": "Submenu 1", "Contents": "This is an example of the first sub-menu", "SourceType": "Text" }, { "Title": "Submenu 2", "Contents": "This is the second sub-menu", "SourceType": "Text" }, { "Title": "GitHub System Status", "Contents": "{\"status\":\"ERROR\",\"body\":\"If you see this, the data failed to load\"}", "Source": "https://status.github.com/api/last-message.json", "SourceType": "RestGet" }, { "Title": "TF2 Blog RSS", "Contents": "If you see this message, an error has occurred", "Source": "http://www.teamfortress.com/rss.xml", "SourceType": "Rss" }, { "Title": "Submenus Test", "Contents": "Testing the submenu functionality", "Submenus": [ { "Title": "Submenu 1", "Contents": "This is an example of the first sub-menu", "SourceType": "Text" }, { "Title": "Submenu 2", "Contents": "This is the second sub-menu", "SourceType": "Text" } ] } ], "SourceType": "Text" }
It seems to me that he has problems with deserializing nested objects, how can I get around this?