Using Custom Contract Resolvers for JSON.NET

The C2 Group
The C2 Group
Published in
3 min readJul 17, 2018

--

By Brian Oliver | Originally published at www.c2experience.com

So, a funny thing happened the other day. I don’t mean “funny” as in “orange you glad I didn’t say banana,” and I definitely don’t mean funny as in a moose wearing a bikini.

I was writing an application that needed to consume a third-party web service to get seven-day weather forecast data. The web service returned a JSON-formatted array of objects, so I created a .NET object and used the Newtonsoft JSON.Net library to deserialize the array. The web service used one-letter property names, and I wanted to have something a little more descriptive in my code, so I used the JSONProperty attribute:

The web service returned an array of these extended forecast objects — one for each of the next seven days, so I used this code to deserialize the result:

This all worked swimmingly. Life was good…but then the funny thing happened. I also needed to consume a web service to get a 36-hour forecast, but this was a web service that did not yet exist (OK, so when I said this was a funny thing, I actually meant it was funny in the sense that it made me want to bang my head against a wall). When this web service became available, I discovered that it was returning the same exact data but with different property names. I would need the following class to deserialize the data from this new web service:

The problem was that I already had this class. Could I name it something else… ExtendedForecast2, perhaps? That just didn’t sit right with me. It’s the same type of data, so I should be able to use the same class for each of the web services, shouldn’t I?

The solution? Custom contract resolvers. JSON.Net has a class called DefaultContractResolver that I can inherit and use in my JSONSerializationSettings. This class defines a method named ResolvePropertyName, which is what JSON.Net will call for each JSON property to determine to which property name on my C# class it corresponds. I’m going to use this contract resolver concept to replace the JSONProperty attributes.

I’m going to need two contract resolvers, one for each web service, and I want a way to use LINQ expressions to specify which property I’m mapping. I want to be able to do this in the constructor of each contract resolver:

In this example, the first five properties map to JSON properties with identical names. The sixth property maps to a different name in the JSON. To start with, I need a base class with three basic components: first, a dictionary for storing the C# property name (key) and JSON property name (value) for each property; second, an AddMap method that will take an LINQ expression, turn it into a C# property name, and add it to the dictionary; and third, an override of the ResolvePropertyName method that will take the property name passed in and look it up in the dictionary.

Step One, the dictionary. That’s easy:

Step Two, the real magic, the AddMap method. I’m going to need two versions of this method. One will take just the expression (for when the C# name and JSON name are identical), and the other will take the expression and the JSON property name:

Step Three, the override method:

Notice that the AddMap is only generic on U. The other generic type (T) will be defined on the class. The final base class is shown here:

Now using these contract resolvers is super easy:

We could be done, except I suppose that instead of instantiating the contract resolvers each time we need them, we should have a static instance for each resolver and reuse them, thus saving the time of calling the constructor. With this, the contract resolver would look like this:

And we would use it like so:

The other contract resolver would follow the same pattern.

One last note: it is important to remove all of the JSONProperty attributes from your class when using this method. If you don’t, the name from that attribute (NOT the name of your C# property) will be passed in to the ResolvePropertyName method.

Brian Oliver is a Senior Advanced .NET Developer for The C2 Group.

--

--

The C2 Group
The C2 Group

The C2 Group specializes in designing, developing, and supporting custom enterprise-level CMS and ecommerce solutions.