How to globally set default options for System.Text.Json.JsonSerializer?

C#JsonSerialization.Net Coresystem.text.json

C# Problem Overview


Instead of this:

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};
var so = JsonSerializer.Deserialize<SomeObject>(someJsonString, options);

I would like to do something like this:

// This property is a pleasant fiction
JsonSerializer.DefaultSettings = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};

// This uses my options
var soA = JsonSerializer.Deserialize<SomeObject>(someJsonString); 

// And somewhere else in the same codebase...
// This also uses my options
var soB = JsonSerializer.Deserialize<SomeOtherObject>(someOtherJsonString); 

The hope is to not have to pass an instance of JsonSerializerOptions for our most common cases, and override for the exception, not the rule.

As indicated in this q & a, this is a useful feature of Json.Net. I looked in the documentation for System.Text.Json as well as this GitHub repo for .NET Core. And this one.

There doesn't seem to be an analog for managing JSON serialization defaults in .NET Core 3. Or am I overlooking it?


C# Solutions


Solution 1 - C#

You can create an extension method. Here's an example

I use separate methods vs having to build special settings, so that all the settings will be in a single spot and easily reusable.

public static class DeserializeExtensions
{
	private static JsonSerializerOptions defaultSerializerSettings = new JsonSerializerOptions();
	
	// set this up how you need to!
	private static JsonSerializerOptions featureXSerializerSettings = new JsonSerializerOptions();


	public static T Deserialize<T>(this string json)
	{		
		return JsonSerializer.Deserialize<T>(json, defaultSerializerSettings);
	}
	
	public static T DeserializeCustom<T>(this string json, JsonSerializerOptions settings)
	{
		return JsonSerializer.Deserialize<T>(json, settings);
	}
	
	public static T DeserializeFeatureX<T>(this string json)
	{
		return JsonSerializer.Deserialize<T>(json, featureXSerializerSettings);
	}
}

Then you call it as a method on a string, whether literal or a variable.

	Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();

Solution 2 - C#

No, JsonSerializerOptions does not expose the default options. If you are using a particular web framework there may be a way to specify (de-)serialization settings through that. Otherwise, I suggest creating your own convenience methods.

See also this open issue.

Solution 3 - C#

The default options are not exposed in JsonSerializer for .NET Core 3.1. However, as of December, 2019 this has been added to the road map for 5.0.

The release of .NET 5.0 is expected November, 2020. But there's no guarantee this particular issue will be addressed at any particular time. Other than waiting, these answers suggest workarounds:

Also, I packaged my convenience extension methods, inspired by @ps2goat's answer and put them on nuget.org and github:

Solution 4 - C#

This seemed to work for me, in StartUp.ConfigureServices:

services.AddControllers().AddJsonOptions(options =>
	{
		options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
		options.JsonSerializerOptions.PropertyNamingPolicy=JsonNamingPolicy.CamelCase;
	});

Solution 5 - C#

A workaround has been proposed by GitHub user andre-ss6 as follows:

((JsonSerializerOptions)typeof(JsonSerializerOptions)
    .GetField("s_defaultOptions", 
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.NonPublic).GetValue(null))
    .PropertyNameCaseInsensitive = true;

Solution 6 - C#

(If you ever switch to using Json.NET)

I prefer and recommend being explicit and pass settings to all calls, but you can set defaults with DefaultSettings.

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

and then

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTrevor ReidView Question on Stackoverflow
Solution 1 - C#ps2goatView Answer on Stackoverflow
Solution 2 - C#Chris YungmannView Answer on Stackoverflow
Solution 3 - C#Trevor ReidView Answer on Stackoverflow
Solution 4 - C#JohnView Answer on Stackoverflow
Solution 5 - C#Trevor ReidView Answer on Stackoverflow
Solution 6 - C#tymtamView Answer on Stackoverflow