If you've read my previous article about How To Searlise And Deseralise Your C# Objects With Json.NET then you'll know how easy it is to serialize your C# objects into JSON so you can store them in a database, CSV file, or whatnot. One thing that my last article didn't cover was how to deal with interfaces with Json.Net. Interface conversion definitely seems to confuse people, so in this follow-up article, I will cover all the code you need to convert an interface into JSON.
If you're a regular reader of my tutorials, you'll know that I constantly encourage developers to learn about dependency injection and mocking. Code following these standards has a much higher probability that it will be well written, flexible, easier to maintain and also that it can be unit tested. If you want to write testable code, then you'd better get used to writing a lot of interfaces. When we work with interfaces, the good news is that serialization will work exactly the same with JSON.NET as a normal instance class. You won't need to do anything differently. If you attempt to deserialize your data back to an interface, you'll see this error:
Could not create an instance of type ''. Type is an interface or abstract class and cannot be instantiated
What's happening here is hopefully obvious. When you serialize an object with an interface JSON.NET can figure out everything that it needs. It has the properties and it can convert it into a string. When it tries to deserialize it though, the original object is no longer alive in memory and it hasn't got a clue what to do with the interface. It cants create a C# class based on an interface magically so it throws a hissy fit 😫 😾😫 😾 What we need then is to fix the deserialize process, read on to learn how!
How To Cast An Interface for Deserialization in JSON.NET
Let' us start with a simple interface:
An example of how a class that implements this interface is shown below:
One solution to make JSON.NET work nicely with interfaces is to explicitly tell the deserializer what type
of object it should be converting the data into. This can be done via an attribute, the JsonConverterAttribute
. JsonConverterAttribute
allows you to specify a custom JSON converter to handle serialization and deserialization of any object type. This is done by extending JsonConverter
:
In the code above, as well as using JsonConverterAttribute
I am also using something called ConcreteTypeConverter
. The converter is used to pass in the type and perform any mappings. The code for CustomConvertor
would look like this:
In the code above, CanConvert()
and WriteJson()
both need to be overridden, however, both methods pretty much work the same way JSON.NET does by default. It's the ReadJson()
method where the biggest differences occur. This is a method where we need to mix things up. In the converter, we're passing in a generic type TConcrete
. In ReadJson()
that we used that passed in type, to tell Json.NET what type it should convert the data into. That's the secret to deserializing with JSON.NET. Happy Coding 🤘