Override JSON.net Serialization Settings Back To Default

Now the title of this post is probably a bit of a mouthful and maybe isn’t what you think. This isn’t about overriding the default settings of JSON.net, it’s about overriding JSON.net *back* to default. That probably doesn’t make a heck of a lot of sense, but hopefully by the end of this post it will!

Returning Enums as Strings In ASP.net Core

If you are returning an enum from an ASP.net Core Web project, by default it’s going to return as the integer representation.

So for example if we have a model that contains an enum that looks like this :

This model will (by default) be serialized looking like so :

Which makes sense. It’s better that we return the integer values in most cases because these become the immutable “key” values, whereas the name of the actual enum can change.

However in some cases, we may want to return a string value. This could be because you have a pesky Javascript/IOS developer who wants string values and won’t budge, or maybe you just prefer it that way! In either case, there is a way to override the model serialization on a per class basis.

All we have to do is decorate our property with a special attribute.

You will require two using statements to go along with this one :

What this does is tell JSON.net (Which as of writing, is the default JSON serializer of .NET Core), to serialize this particular property using the StringEnumConverter. Which among other things, can just use the string representation of an enum. If we serialize this model now, we get :

But the problem we now have is that we have to go and edit every single property that uses an enum and tell it to use the string representation. If we know we want it in every case across the board, then we can actually tell JSON.net to use the StringEnumConverter everytime.

Head over to our startup.cs and find the ConfigureServices method. In there we should already see a call to AddMvc(), and we are just going to tack onto the end of this.

Here we are basically saying that here’s a converter you can use anytime it’s applicable (Which is basically for every Enum), so go ahead and use it.

The Problem (And The Fix)

If we have been humming along serializing enums as strings, we might end up in a position where we actually do want to return an enum as an integer. A prime example of this (At least it was for me), is returning error codes. I want the codes to be represented in C#  as enums as it’s much easier to wrangle, but be serialized out as simple numeric code.

So what we now want to do is override our “new default” of StringEnumConverter, and go back to the old way of doing things. So how do we do that? Well actually we can’t. As crazy as that probably sounds, I couldn’t find any way  to say “Please use the default converter instead of that other one I gave you”.

Thinking that I was going to have to write my own custom converter just to cast back to an int, I came across an interesting little piece of documentation. It came of the form of the “CanWrite” property of a custom converter. The documentation of which is here : https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonConverter_CanWrite.htm

Note that if this is set to false, it’s saying that the JsonConverter cannot write the JSON. So what is it going to fall back to? As it turns out, the default converter for that type.

So all we need to do is whip up a custom JSON converter that does absolutely nothing :

The NotImplemented methods are ones that I must have when I inherit from the base class. But because I set CanRead and CanWrite to false, they are never actually called.

Now if we decorate our enum property with this converter (Essentially forcing it to use no other custom converters even if they are in the setup list in our startup.cs)

Serializing this model again we get :

Perfect!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Leave a Reply

Your email address will not be published. Required fields are marked *