Premetto che so qual è il problema, ma non so come risolverlo. Sto comunicando con un livello dati SOA .NET che restituisce i dati come JSON. Uno di questi metodi restituisce un oggetto che contiene diverse raccolte al suo interno. L'oggetto si presenta sostanzialmente in questo modo:Il tipo è un'interfaccia o classe astratta e non può essere istanziato
{
"Name":"foo",
"widgetCollection":[{"name","foo"}, {"name","foo"},],
"cogCollection": [{"name","foo"}, {"childCogs",<<new collection>>},],
}
mia classe che rappresenta l'oggetto si presenta così:
public class SuperWidget : IWidget
{
public string Name { get; set; }
public ICollection<IWidget> WidgetCollection { get; set; }
public ICollection<ICog> CogCollection { get; set; }
public SuperWidget()
{
}
[JsonConstructor]
public SuperWidget(IEnumerable<Widget> widgets, IEnumerable<Cog> cogs)
{
WidgetCollection = new Collection<IWidget>();
CogCollection = new Collection<ICog>();
foreach (var w in widgets)
{
WidgetCollection.Add(w);
}
foreach (var c in cogs)
{
CogCollection.Add(c);
}
}
}
Questo costruttore ha funzionato bene fino a quando il cogCollection aggiunto una collezione bambino, e ora sto ottenendo quanto sopra errore. Una classe COG concreta si presenta così:
[Serializable]
public class Cog : ICog
{
public string name { get; set; }
public ICollection<ICog> childCogs { get; set; }
}
Io non voglio cambiare la collezione ad un tipo concreto perché sto usando CIO. Perché sto usando IoC mi piacerebbe davvero allontanarmi dalla necessità di avere i JsonConstructors che prendono parametri concreti, ma non ho trovato un modo per farlo. Qualsiasi consiglio sarebbe molto apprezzato!
Aggiornamento: il suggerimento di
Yuval Itzchakov che questa domanda è probabilmente un duplicato è un po 'vero (a quanto pare). Nel post referenziato, una delle risposte nella pagina fornisce la stessa soluzione che è stata fornita qui. Non ho notato quella risposta, dal momento che la domanda dell'OP era diversa da quella che avevo qui. Errore mio.
------- -------- mia soluzione
Come ho già detto: la soluzione di Matt ha preso un po 'di lavoro ma ho ottenuto l'installazione qualcosa che funziona per me. L'unica cosa che non mi piace per la sua soluzione iniziale, erano righe come queste:
return objectType == typeof(ICog);
Seguendo questo schema si avrebbe bisogno di avere un JsonConverter per ogni tipo astratto che si riceve sul filo. Questo è proprio l'ideale nella mia situazione, così ho creato un JsonConverter generica in quanto tale:
public class GenericJsonConverter<T>: JsonConverter, IBaseJsonConverter<T>
{
private readonly IUnityContainer Container;
public TalonJsonConverter(IUnityContainer container)
{
Container = container;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var target = serializer.Deserialize<Newtonsoft.Json.Linq.JObject>(reader);
var result = Container.Resolve<T>();
serializer.Populate(target.CreateReader(), result);
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
Poi, proprio prima che io deserializzare i miei dati, faccio qualcosa di simile:
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
settings.Converters.Add((JsonConverter)Container.Resolve<IBaseJsonConverter<ICog>>());
Protip: Se usa Resharper, (JsonConverter) ti darà un cast cast sospettoso in questo scenario.
Speriamo che qualcun altro trovi utile questo in fondo alla strada!
Provare a usare 'TypeNameHandling.All' della classe' JsonSerializerSettings' e passarlo al serializzatore json –
possibile duplicato di [Interfacce di fusione per la deserializzazione in JSON.NET] (http://stackoverflow.com/questions/5780888/ casting-interface-per-deserialization-in-json-net) –
possibile duplicato di [Utilizzo dei convertitori Json.NET per deserializzare le proprietà] (http://stackoverflow.com/questions/2254872/using-json-net-converters-to -deserialize-properties) – nawfal