I would like to serialize this code via json.net:
public interface ITestInterface
{
string Guid {get;set;}
}
public class TestClassThatImplementsTestInterface1
{
public string Guid { get;set; }
}
public class TestClassThatImplementsTestInterface2
{
public string Guid { get;set; }
}
public class ClassToSerializeViaJson
{
public ClassToSerializeViaJson()
{
this.CollectionToSerialize = new List<ITestInterface>();
this.CollectionToSerialize.add( new TestClassThatImplementsTestInterface2() );
this.CollectionToSerialize.add( new TestClassThatImplementsTestInterface2() );
}
List<ITestInterface> CollectionToSerialize { get;set; }
}
I want to serialize/deserialize ClassToSerializeViaJson with json.net. Serialization is working, but deserialization gives me this error:
Newtonsoft.Json.JsonSerializationException: Could not create an instance of type ITestInterface. Type is an interface or abstract class and cannot be instantiated.
So how can I deserialize the List<ITestInterface>
collection?
Near-duplicate of Inrego's answer, but it's worthy of further explanation:
If you use
TypeNameHandling.Auto
then it only includes the type/assembly name when it needs to (i.e. interfaces and base/derived classes). So your JSON is cleaner, smaller, more specific.Which isn't that one of the main selling points of it over XML/SOAP?
I found this question while trying to do this myself. After I implemented Garath's answer, I was struck by how simple it seemed. If I was merely implementing a method that was already being passed the exact Type (as a string) that I wanted to instantiate, why wasn't the library binding it automatically?
I actually found that I didn't need any custom binders, Json.Net was able to do exactly what I needed, provided I told it that was what I was doing.
When serializing:
When de-serializing:
Relevant documentation: Serialization Settings for Json.NET and TypeNameHandling setting
It can be done with JSON.NET and JsonSubTypes attributes:
and simply:
Using the default settings, you cannot. JSON.NET has no way of knowing how to deserialize an array. However, you can specify which type converter to use for your interface type. To see how to do this, see this page: http://blog.greatrexpectations.com/2012/08/30/deserializing-interface-properties-using-json-net/
You can also find information about this problem at this SO question: Casting interfaces for deserialization in JSON.NET
I wanted to deserialize JSON that wasn't serialized by my application, hence I needed to specify the concrete implementation manually. I have expanded on Nicholas's answer.
Lets say we have
and the concrete instance of
Add in this class
Then define your interfaces with the JsonConverter attribute
I was also surprised by the simplicity in Garath's, and also came to the conclusion that the Json library can do it automatically. But I also figured that it's even simpler than Ben Jenkinson's answer (even though I can see it has been modified by the developer of the json library himself). From my testings, all you need to do is set TypeNameHandling to Auto, like this: