如何全局设置 System.Text.Json.JsonSerializer 的默认选项?

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

而不是这个:

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

我想做这样的事情:

// 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); 

希望在我们最常见的情况下不必传递 JsonSerializerOptions 的实例,并覆盖例外情况,而不是规则。

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所示。

.NET Core 3 中似乎没有用于管理 JSON 序列化默认值的模拟。还是我忽略了它?


不,JsonSerializerOptions 不公开 default options。如果您使用的是特定的 Web 框架,则可能有一种方法可以通过它指定(反)序列化设置。否则,我建议创建您自己的便捷方法。

另见 this open issue

您可以创建扩展方法。 Here's an example

我使用不同的方法而不是必须构建特殊设置,这样所有设置都将位于一个位置并且易于重复使用。

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);
    }
}

然后你将它作为字符串的方法调用,无论是文字还是变量。

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

(如果您改用 Json.NET)

我更喜欢并建议明确并将设置传递给所有调用,但您可以使用 DefaultSettings.

设置默认值
JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

然后是

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

一个workaround has been proposed by GitHub user andre-ss6如下:

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

.NET Core 3.1 的 JsonSerializer 中未公开默认选项。但是,截至 2019 年 12 月,5.0 已 added to the road map

.NET 5.0 的发布时间是 expected 2020 年 11 月。但是不能保证这个特定问题会在任何特定时间得到解决。除了等待之外,这些答案还提供了解决方法:

此外,我打包了我的便利扩展方法,灵感来自@ps2goat 的回答,并将它们放在 nuget.org and github:

这似乎对我有用,在 StartUp.ConfigureServices:

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