【发布时间】:2021-05-23 20:57:27
【问题描述】:
在 asp.net core 3.1 中,使用新的 System.Text.Json,我试图在 appsettings 部分使用自定义 JsonConverter。手动序列化/反序列化尊重转换器就好了,但通过选项模式从 appSettings 读取则不行。这是我所拥有的:
JsonConverter。为简单起见,这只是将字符串值转换为大写:
public class UpperConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
reader.GetString().ToUpper();
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) =>
writer.WriteStringValue(value == null ? "" : value.ToUpper());
}
appsettings 类,在字符串属性上声明转换器:
public class MyOptions
{
public const string Name = "MyOptions";
[JsonConverter(typeof(UpperConverter))]
public string MyString { get; set; }
}
Startup.cs 更改以准备一切:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new UpperConverter());
});
services.Configure<MyOptions>(Configuration.GetSection(MyOptions.Name));
}
当我将IOptions<MyOptions> 注入 HomeController 时,它会读取一个小写值。如果我手动执行JsonSerializer.Deserialize<MyOptions>("{\"MyString\":\"lowercase_manual\"}"),我会得到一个大写字符串。即使我删除了 JsonSerializerOptions 的 Startup 声明。
有谁知道如何让 appsettings / options 模式尊重 JsonConverter?我必须在其他地方声明 JsonSerializerOptions 吗?谢谢。
【问题讨论】:
-
他们不是故意的,也不是必须的。 JsonConverter 选项适用于 ASP.NET 请求和响应解析。 Microsoft.Extensions.Configuration 是一个单独的包,供所有 类型的项目(包括控制台项目)使用。
appsettings.json不是一个特殊文件,它只是用于使用许多可用配置提供程序之一加载设置的常规名称。 JSON 提供程序使用文档中描述的特定格式加载设置。 所有设置,无论来源(json、ini、数据库、环境)如何,都存储为键/值对。 -
为什么要使用 JsonConverter?您不能使用它来构造对象,这些对象是根据从所有提供程序加载的键/值对构造的。如果要将加载的值转换为大写 - 为什么?如果大小写很重要,您不应该保留大小写,还是确保存储 正确 大小写?如果不是,您可以对这些值使用不区分大小写的比较或不区分大小写的字典
-
如果您想以特定方式加载设置,您可以创建自己的设置提供程序。我怀疑真正的问题是需要大写
-
如果您需要大写设置,则需要将转换应用于所有设置,无论来源如何。这意味着您应该在绑定期间转换值,而不是在从某个特定提供程序加载期间。更好的是,为什么不更改
MyString的设置器以将值存储为大写? -
我想我在这里寻找的具体答案是 JsonConfigurationProvider 从不调用
JsonSerializer.Deserialize,因为正如您指出的那样,它不需要,它只是用于创建键值对。它调用JsonDocument.Parse来代替这项工作。感谢您的帮助。
标签: c# asp.net-core .net-core application-settings jsonconverter