如何为 System.Text.Json.JsonSerializer 全局设置默认选项?
Posted
技术标签:
【中文标题】如何为 System.Text.Json.JsonSerializer 全局设置默认选项?【英文标题】:How to globally set default options for System.Text.Json.JsonSerializer? 【发布时间】:2020-02-08 09:42:31 【问题描述】:而不是这个:
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 所示,这是 Json.Net 的一个有用功能。我在the documentation 中查看了System.Text.Json
以及this GitHub repo 中的.NET Core。还有this one。
在 .NET Core 3 中似乎没有管理 JSON 序列化默认值的类比。还是我忽略了它?
更新 [2020-07-18]: 请参阅 this answer 了解 nuget package 以及支持默认设置的便捷方法。
更新 [2019 年 12 月 23 日]: 部分由于 community input 这个问题在 .NET 5.0 中是 added to the roadmap。
更新 [2019-10-10]: 如果有兴趣看到为 System.Text.Json.JsonSerializer
实施此行为,请前往致Chris Yungmann指出的the open GitHub issue并称重。
【问题讨论】:
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3
-- 您是在谈论进出 API 的请求吗?还是对其他资源的请求和响应?
@ps2goat 我不确定我是否理解您的问题。这里的问题是(反)序列化 JSON 字符串。它们可以来自任意数量的来源。
我之所以问,是因为在启动过程中有一些特殊的地方用于输入和输出格式化程序(例如,用于模型绑定)
啊,明白了。从这个意义上说,我认为我们的案例将属于“其他资源”。 @ps2goat
【参考方案1】:
您可以创建扩展方法。 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>();
【讨论】:
【参考方案2】:不,JsonSerializerOptions
不会公开default options。如果您使用的是特定的 Web 框架,则可能有一种方法可以通过它指定(反)序列化设置。否则,我建议您创建自己的便捷方法。
另见this open issue。
【讨论】:
【参考方案3】:默认选项未在 .NET Core 3.1 的 JsonSerializer
中公开。但是,截至 2019 年 12 月,对于 5.0,这一直是 added to the road map。
.NET 5.0 的发布日期为 expected2020 年 11 月。但不能保证此特定问题会在任何特定时间得到解决。除了等待之外,这些答案还提供了一些解决方法:
https://***.com/a/58331912/1011722 https://***.com/a/58959198/1011722此外,受@ps2goat 的回答启发,我打包了我的便利扩展方法,并将它们放在nuget.org 和github 上:
https://www.nuget.org/packages/Fetchgoods.Text.Json.Extensions/【讨论】:
【参考方案4】:这似乎对我有用,在 StartUp.ConfigureServices 中:
services.AddControllers().AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
options.JsonSerializerOptions.PropertyNamingPolicy=JsonNamingPolicy.CamelCase;
);
【讨论】:
它确实有效。但是,它特定于配置控制器。 @TrevorReid 好点,如果你例如,这是一个问题。使用 Refit 从您的 asp.net 核心进行 API 调用 --> 然后 Refit 将忽略这些设置。【参考方案5】:GitHub用户andre-ss6提出了一个workaround,如下:
((JsonSerializerOptions)typeof(JsonSerializerOptions)
.GetField("s_defaultOptions",
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic).GetValue(null))
.PropertyNameCaseInsensitive = true;
【讨论】:
这很好用,但很脆弱。我将使用它(我正在注册自定义类型转换器,不更改 PropertyNameCaseInsensitive,但前提是相同的)并祈祷它一直有效,直到 2020 年 11 月的预期发布,官方支持设置默认选项。 工作正常!谢谢【参考方案6】:(如果你曾经改用 Json.NET)
我更喜欢并建议使用明确的设置并将设置传递给所有调用,但您可以使用 DefaultSettings 设置默认值。
JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;
然后
var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
【讨论】:
我猜你被否决了,因为问题是指 System.Text.Json 而不是 Newtonsofts (更好)包。在我的情况下,我没有选择“切换”到 Json.Net,因为在这个 Blazor Web 组装项目中该选项已被我拿走了。它远非伟大,它就是这样 “好多了”是一个观点问题——Newtonsoft.JSON 在配置和支持怪异(甚至无效的 json)方面肯定是“更好”的。但是,System.Text.Json 在性能(内存和 CPU)方面更好。以上是关于如何为 System.Text.Json.JsonSerializer 全局设置默认选项?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 RecyclerView 设置 onItemClickListener? [复制]