IConfiguration.Get<>() 无法检索那些属性为空数组的元素

编程语言 2026-07-08

我正在尝试从我的 appsettings.json 导入我的 ServerProcessConfig[]。如果数组中有一个元素在 Dependencies 上是一个空数组,它就无法导入整个配置对象。

尝试了是否允许空值的两种情况。

using Microsoft.Extensions.Configuration;
var configuration = new ConfigurationBuilder()
    .SetBasePath(AppContext.BaseDirectory)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .Build();

var servers = configuration
    .GetSection("Servers")
    .Get<List<ServerProcessConfig>>()!;
Console.WriteLine(servers.Count);
public sealed record ServerProcessConfig(
    int Id,
    int[]? Dependencies);

Servers 数组中的以下元素被跳过,因此检索到的服务器配置数量为1。尝试了空数组的情况,并尝试移除该属性。

appsettings.json

  {"Servers": [
    {
      "Id": 1,
      "Dependencies": []
    },
    {
      "Id": 2,
      "Dependencies": [1]
    },    
  ]}

这有效,元素出现在 servers[] 中,servers 的长度为2。

    {
      "Id": 1,
      "Dependencies": [0]
    }

解决方案

我能够在.NET 10中重现你的问题,失败的演示fiddle #1可以在这里看到 这里。问题似乎出在对具有参数化构造函数的类型进行绑定时,因为我也能够在等效的带参数的类中重现完全相同的行为:

public sealed class ServerProcessConfig // Also does not bind when Dependencies has Length zero.
{
    public ServerProcessConfig(int Id, int[]? Dependencies) => (this.Id, this.Dependencies) = (Id, Dependencies);

    public int Id { get; }
    public int[]? Dependencies { get; }
}

请在这里查看失败的演示fiddle #2:这里

作为一种变通方法,我建议用 public required ... { get; init; } 属性替换参数化属性,像这样:

public sealed record ServerProcessConfig
{
    public required int Id { get; init; }
    public required int[]? Dependencies { get; init; }
}

使用这个版本的 ServerProcessConfig,设置数组绑定成功。(具有相同属性的类也可以工作。)

请在这里查看可运行的演示fiddle #3:这里

并且,正如 Ivan Petrov 在评论中提到的,添加一个无参构造函数也能解决这个问题:

public sealed record ServerProcessConfig(
    int Id,
    int[]? Dependencies)
{
    public ServerProcessConfig() : this(-1, null) { }
}

采用这种方式,位置属性不再是必需的,因此下面的代码现在可以编译:

var test1 = new ServerProcessConfig { Id = 101 }; // Note - still seems to compile  even without setting Dependencies

可运行的fiddle #4请在这里:这里

你可以考虑向微软报告这个问题;一般来说,绑定具有带有数组值参数的参数化构造函数的类型是受支持的,因此在数组长度为零时绑定失败就显得奇怪。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章