Type is an interface or abstract class and cannot be instantiated
c#, json, json.net
Solution
You'll need to provide a custom serializer to Json.Net to tell it how to handle the child cogs. For example:
var settings = new JsonSerializerSettings();
settings.Converters.Add(new CogConverter());
Your `CogConverter` will need to inherit from `JsonConverter` and specify that it `CanConvert` your `ICog` interface. Perhaps something along the lines of:
public class CogConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ICog);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize(reader, typeof(Cog));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
I'd recommend registering your `JsonSerializerSettings` with your IoC container in that case. You may want to consider giving `CogConverter` access to the container, too, if the serializer can't be responsible for actually constructing the `Cog` itself; that all depends on your particular architecture.
Edit
Upon further reading, it seems like you might be looking for specifically how to use the IoC created `ICog` for population. I'm using the following as part of my ReadJson:
var target = serializer.Deserialize<Newtonsoft.Json.Linq.JObject>(reader);
var objectType = DetermineConcreteType(target);
var result = iocContainer.Resolve(objectType);
serializer.Populate(target.CreateReader(), result);
return result;
This allows you to use ANY object and populate it from the original JSON, using custom types as you wish inside your `DetermineConcreteType` method.
Problem
I will preface this by saying that I know what the problem is, I just don't know how to solve it. I am communicating with a .NET SOA data layer that returns data as JSON. One such method returns an object that has several collections within it. The object basically looks like this: ``` { "Name":"foo", "widgetCollection":[{"name","foo"}, {"name","foo"},], "cogCollection": [{"name","foo"}, {"childCogs",<<new collection>>},], } ``` My class that represents this object looks like this: ``` 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); } } } ``` This constructor worked fine until the cogCollection added a child collection, and now I am getting the above error. A concrete cog class looks like this: ``` [Serializable] public class Cog : ICog { public string name { get; set; } public ICollection<ICog> childCogs { get; set; } } ``` I don't want to change the collection to a concrete type because I am using IoC. Because I am using IoC I would really like to get away from the need to have the JsonConstructors that take concrete parameters, but I haven't figured out a way to do that. Any advice would be greatly appreciated! Update: Yuval Itzchakov's suggestion that this question is probably a duplicate is somewhat true (it seems). In the post referenced, one of the answers down the page provides same solution that was provided here. I didn't notice that answer, since the OP's question was different then the one I had here. My mistake. -------my solution-------- As I said: Matt's solution took a little bit of work but I got something setup that works for me. The one thing I didn't like about his initial solution, were lines like these: ``` return objectType == typeof(ICog); ``` Following this pattern you would need to have a JsonConverter for every abstract type that you receive over the wire. This is less than ideal in my situation, so I created a generic JsonConverter as such: ``` public class GenericJsonConverter<T>: JsonConverter, IBaseJsonConverter<T> { private readonly IUnityContainer Container; public GenericJsonConverter(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); } } ``` Then just before I deserialize my data, I do something like this: ``` var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }; settings.Converters.Add((JsonConverter)Container.Resolve<IBaseJsonConverter<ICog>>()); ``` Protip: If you use Resharper, (JsonConverter) will give you a suspicious cast warning in this scenario. Hopefully someone else finds this useful down the road!