You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core:如何将appsettings.json配置节读取为不可变记录

如何将appsettings.json配置节读取为带不可变集合的不可变记录?

问题场景

假设你的appsettings.json有如下配置:

{
  "MySection": {
    "Id": 5,
    "Names": { "John": "Manager", "Sally": "Boss" }
  }
}

需要将MySection转换为以下不可变记录类型:

public record MyConfig(int Id, ImmutableDictionary<string, string> Names);

直接使用Configure<T>会报错:

serviceCollection.Configure<MyConfig>(this.Configuration.GetSection("MySection"));

UnhandledException... ...Cannot dynamically create an instance of type 'MyConfig'. Reason: No parameterless constructor defined.

原因是默认配置绑定系统要求目标类型有公共无参构造函数,且属性支持设置,而不可变记录的主构造函数没有无参版本,同时不可变集合也无法被默认绑定系统处理。

简洁解决方案

方案1:使用Configuration.Get<T>直接获取(推荐)

在.NET 6及以上版本中,Configuration.GetSection().Get<T>()方法内部基于System.Text.Json实现,天然支持不可变记录和不可变集合(包括ImmutableDictionary)。

代码示例:

// 从配置节读取并反序列化为不可变记录实例
var myConfig = Configuration.GetSection("MySection").Get<MyConfig>();

// 将实例注册到依赖注入容器
serviceCollection.AddSingleton(myConfig);

如果需要通过IOptions<MyConfig>方式访问,可结合AddOptions注册:

serviceCollection.AddOptions<MyConfig>()
    .Configure<IConfiguration>((_, config) =>
    {
        return config.GetSection("MySection").Get<MyConfig>();
    });

注:若使用IOptions,更推荐直接注册实例的方式,避免不必要的配置逻辑。

方案2:自定义配置绑定转换器(兼容旧版本)

如果你的项目基于.NET 5或更早版本,可自定义配置绑定的转换器来处理不可变集合和记录:

public static class ConfigurationExtensions
{
    public static T GetImmutable<T>(this IConfiguration configuration)
    {
        var json = JsonSerializer.Serialize(configuration.AsEnumerable());
        return JsonSerializer.Deserialize<T>(json, new JsonSerializerOptions
        {
            Converters = { new JsonImmutableDictionaryConverter<string, string>() }
        });
    }
}

// 使用方式
var myConfig = Configuration.GetSection("MySection").GetImmutable<MyConfig>();
serviceCollection.AddSingleton(myConfig);

关于“读取配置节为JSON字符串”的实现

如果确实需要将配置节转为JSON字符串,可通过以下方式实现:

var configDict = Configuration.GetSection("MySection")
    .AsEnumerable()
    .Where(kv => !string.IsNullOrEmpty(kv.Value))
    .ToDictionary(kv => kv.Key, kv => kv.Value);

var json = JsonSerializer.Serialize(configDict);

但此方法较为迂回,仅在特殊场景下使用。

内容的提问来源于stack exchange,提问作者MLavrentyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:42:55