Sto cercando di deserializzare alcuni JSON a varie sottoclassi utilizzando un custom JsonConverter
polimorfico JSON deserializzazione non riuscendo utilizzando Json.Net
ho seguito this quasi al punto.
mio astratta della classe base:
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();
}
E il mio derivato 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
è solo una classe statica contenente alcune costanti di stringa.
Il file JSON viene deserializzato in questo modo:
JsonConvert.DeserializeObject<MenuItem>(File.ReadAllText(menuPath), new MenuItemConverter());
Ora, il mio problema è che ogni volta che esegue il codice ottengo il seguente errore:
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.
Il file JSON in questione si presenta come this:
{
"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"
}
Mi sembra che abbia problemi di deserializzazione dell'oggetto nidificato s, come faccio ad aggirarlo?
ho scoperto che ho avuto esattamente lo stesso errore se ho usato il JsonConvert.DeserializeObject e superato un impostazioni serializzatore con mio convertitore aggiunto. Quando ho usato lo stesso sovraccarico di come ha funzionato ... Non so se questo sia il JsonSerializer in errore o la mia comprensione delle impostazioni del serializzatore. –