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

Tre*_*eid 37 c# serialization json .net-core system.text.json

取而代之的是:

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

我想做这样的事情:

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

Run Code Online (Sandbox Code Playgroud)

希望不必JsonSerializerOptions为我们最常见的情况传递一个实例,并覆盖异常而不是规则。

问答中所示,这是 Json.Net 的一个有用功能。我看着在文档System.Text.Json以及这个GitHub库为.NET的核心。还有这个

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


ps2*_*oat 15

您可以创建扩展方法。这是一个例子

我使用单独的方法而不是必须构建特殊设置,以便所有设置都在一个地方并且可以轻松重复使用。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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


Chr*_*ann 12

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

另请参阅此未解决的问题


Tre*_*eid 10

JsonSerializer.NET Core 3.1中未公开默认选项。但是,截至 2019 年 12 月,这已添加到5.0的路线图中。

.NET 5.0预计于 2020 年 11 月发布。但不能保证这个特定问题会在任何特定时间得到解决。除了等待,这些答案提出了解决方法:

此外,我打包了我的便利扩展方法,灵感来自@ps2goat 的答案,并将它们放在nuget.orggithub 上


Tre*_*eid 7

GitHub 用户andre-ss6提出了一种解决方法,如下所示:

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

  • 修复: `public static void SetIgnoreNulls() =&gt; typeof(JsonSerializerOptions).GetRuntimeFields().Single(f =&gt; f.Name == "_defaultIgnoreCondition").SetValue(JsonSerializerOptions.Default, JsonIgnoreCondition.WhenWritingNull);` 为什么这么复杂:https://github.com/dotnet/runtime/issues/15643 (2认同)

小智 6

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

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

  • 它确实有效。然而,它特定于配置控制器。 (19认同)
  • @TrevorReid 好点,如果您使用 Refit 从 asp.net core 进行 API 调用,这就是一个问题 --&gt; 然后 Refit 将忽略这些设置。 (2认同)