配置中保留的 Null 值

.NET 配置绑定器通过配置提供程序检索配置值,并尝试将这些值绑定到对象属性。 以前,当配置值为 null 时,绑定器将其视为值根本不存在,因此跳过了绑定。 换句话说,它不区分 null 值和缺失值。 对于预期在其配置中显式定义 null 值的用户,此行为造成了重大混淆,这些用户应受到尊重和正确绑定。

此外,JSON 配置提供程序以前将配置中的值转换为 null 空字符串。 这进一步导致混淆,因为绑定到这些值的属性将收到空字符串,而不是预期的 null。

此更改解决了这两个问题。 JSON 配置提供程序现在正确报告 null 值而不更改它们,绑定器将值视为 null 有效的输入,像任何其他值一样绑定它们。

此更新还包括对支持数组中的绑定 null 值的改进,并启用空数组的绑定。

已引入的版本

.NET 10

以前的行为

以前,当配置值是 null时,绑定器将其视为值根本不存在,因此跳过了绑定。 系统无法区分 null 值和缺失值。

此外,JSON 配置提供程序将配置中的值转换为 null 空字符串。 这导致绑定到这些值的属性接收空字符串,而不是预期 null

请考虑以下配置文件 appsettings.json 内容:

{
    "NullConfiguration": {
        "StringProperty": null,
        "IntProperty": null,
        "Array1": [null, null],
        "Array2": []
    }
}

以及相应的绑定代码:

public class NullConfiguration
{
    public NullConfiguration()
    {
        // Initialize with non-default value to
        // ensure binding overrides these values.
        StringProperty = "Initial Value";
        IntProperty = 123;
    }
    public string? StringProperty { get; set; }
    public int? IntProperty { get; set; }
    public string[]? Array1 { get; set; }
    public string[]? Array2 { get; set; }
}

var configuration = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .Build().GetSection("NullConfiguration");

// Now bind the configuration.
NullConfiguration? result = configuration.Get<NullConfiguration>();

Console.WriteLine($"StringProperty: '{result!.StringProperty}', intProperty: {(result!.IntProperty.HasValue ? result!.IntProperty : "null")}");
Console.WriteLine($"Array1: {(result!.Array1 is null ?
    "null" : string.Join(", ", result!.Array1.Select(a => $"'{(a is null ? "null" : a)}'")))}");
Console.WriteLine($"Array2: {(result!.Array2 is null ?
    "null" : string.Join(", ", result!.Array2.Select(a => $"'{(a is null ? "null" : a)}'")))}");

输出:

StringProperty: '', intProperty: 123
Array1: '', ''
Array2: null

输出说明:

  • StringProperty null:JSON 提供程序将 JSON 提供程序中的值转换为空字符串(“”),覆盖初始值。
  • IntProperty:保持不变(123),因为提供程序已转换为 null 空字符串,无法将其解析为空 int?字符串,因此保留原始值。
  • Array1:绑定到包含两个空字符串的数组,因为每个 null 数组元素被视为空字符串。
  • Array2:由于绑定器忽略了 JSON 中的空数组null,因此保留[]

新行为

从 .NET 10 开始, null 值现在已正确绑定到相应的属性,包括数组元素。 即使是空数组也正确识别并绑定为空数组,而不是被忽略。

运行同一代码示例会使用 JSON 配置提供程序生成以下结果:

StringProperty: 'null', intProperty: null
Array1: 'null', 'null'
Array2:

破坏性变更的类型

这是行为 变化

更改原因

以前的行为令人困惑,经常导致用户投诉。 通过解决此问题,配置绑定过程现在更加直观且一致,减少了混淆,使行为与用户期望保持一致。

如果更喜欢以前的行为,可以相应地调整配置:

  • 使用 JSON 配置提供程序时,将值替换为 null 空字符串("")以还原原始行为,其中绑定了空字符串,而不是 null绑定空字符串。
  • 对于支持 null 值的其他提供程序,请从配置中删除 null 条目以复制早期行为,其中忽略缺失值,并且现有属性值保持不变。

受影响的 API