Browsed by
Category: c#

Deserializing abstract types using Newtonsoft.Json

Deserializing abstract types using Newtonsoft.Json

Recently I had to integrate with a “delivery” web service that provided it’s own contracts as part of a NuGet package. My immediate thought was “sweet, now I don’t have to do all of that boring typing to add all of the requisite types”. That was until I ran into some code that looks similar to this:

The problem

When making calls to the delivery web service, the response was expected to be of type Delivery which is shown above. The problem is that the Newtonsoft.Json serializer that WebApi uses by default is not able to determine which subclass of BaseDeliverable to use and therefore fails to deserialize the response. While this sucks for me, it’s not the fault of Json.Net as .

My first instinct was to change these contracts entirely so that these objects that were related from a business point of view were not so closely related in the code. That would have involved removing of the base class and adding a property to Delivery for each of the different types of delivery. Unfortunately, despite being the only consumer of the NuGet package, I wasn’t the only consumer of the service and the service itself used this contract package for (correctly) serializing responses to be sent to other clients.

The second option would be to change the delivery service to output type information but again, that would break the contract with the other consumers.

The solution

As I was not able to change the contract itself, I decided to change how the contract would be created when getting a response from the delivery web service. This led me to look into custom converters to see if I could determine which subclass to deserialize to based on the properties that the JSON object has.

After much Googling, I stumbled upon this article which had the majority of the code that I needed but I wanted to make it a bit more generic. Here’s my custom JsonConverter class:

One of the key differences to the example given in the linked article is that this converter takes a Type as a constructor parameter. When constructing the converter, all subtypes of the specified type will be stored. In ReadJson, we determine which type to deserialize to by trying to match all of the public property names on each of the subtypes with the JSON field names present. In this implementation there must be an exact match but this could easily be changed to be more forgiving.

The major learning from the linked article is that you cannot use obj.ToObject<T>(reader) or JsonConvert.DeserializeObject<T>(obj.ToString()) here because the same converter will be instantiated and called resulting in an infinite loop until a stack overflow is thrown! The method shown creates a new instance of the type that we’ve decided that we want and then populates that instance using the serializer which avoids calling the custom converter. Clever!

Conclusion

To be honest, I wish I didn’t have to write this code but it does solve a problem that was blocking me from adding value to the client’s product! I’ve written this post mainly as a reference for myself so I don’t have to do so much Googling if I am ever stuck needing to do this again!