通过


ConfigurationBinder 以无提示方式跳过无效的数组元素

从 .NET 8 开始, ConfigurationBinder 以无提示方式跳过数组和列表元素,其值无法转换为目标类型。 以前,失败的元素保留为 null 占位符,生成的集合保留的长度与配置源中的元素数相同。

已引入的版本

.NET 8

以前的行为

以前,当通过Get<T>(IConfiguration)Bind(IConfiguration, Object)绑定数组或列表属性时,如果无法将元素的值转换为目标类型,该元素将在结果中作为null占位符保留。 集合长度与配置中的元素数匹配。

// Configuration source, for example, appsettings.json:
// "Items": [
//   { "Name": "A", "Interval": 10 },
//   { "Name": "B", "Interval": "a" }   <-- invalid int
// ]

var settings = configuration.GetSection("Items").Get<MyItem[]>();

// .NET 6/7 result:
// settings.Length == 2
// settings[0] = { Name = "A", Interval = 10 }
// settings[1] = null   (conversion failed, placeholder preserved)

新行为

从 .NET 8 开始,将无提示跳过失败类型转换的元素。 生成的集合仅包含已成功绑定的元素,其长度比配置源中的条目数短。

var settings = configuration.GetSection("Items").Get<MyItem[]>();

// .NET 8+ result:
// settings.Length == 1
// settings[0] = { Name = "A", Interval = 10 }

破坏性变更的类型

此更改为行为更改

更改原因

.NET 8 中对 ConfigurationBinder 的内部实现进行了重构。 现在,绑定器不会预先分配目标数组并在原地绑定元素(在转换失败后留下 null),而是将成功绑定的元素收集到一个临时列表中,然后在最终生成数组前进行处理。

对于值类型(如 int[])而言,以前的行为也存在问题。 对于无效的配置值,绑定器将存储 0,这与合法值 0不可区分。 新行为可避免这种歧义。

  • 在开发过程中启用ErrorOnUnknownConfiguration以立即显示无效的配置值,而不是以无提示方式删除元素:

    var settings = configuration.GetSection("Items").Get<MyItem[]>(options =>
        options.ErrorOnUnknownConfiguration = true);
    

    从 .NET 8 开始,此选项还会导致 ConfigurationBinder 在无法转换为目标类型时引发 InvalidOperationException 值。 有关详细信息,请参阅 ConfigurationBinder 在值不匹配时抛出异常

  • 修复无效的配置值。 确保配置源中的所有值都与绑定模型的预期类型匹配。

  • 如果代码依赖于与配置源匹配的元素数,请在绑定后验证集合长度

  • 如果需要正常处理不可转换的值并保留所有数组条目,请使用带手动分析的字符串属性

受影响的 API