为什么属性从配置初始化为null而不是空列表?

时间:2017-10-25 14:52:25

标签: c# asp.net-core

我有一个asp.net-core web api项目,其配置包含以下定义:

"MyClass": {
   "Value1": 1,
   "Value2": []
}

此配置用于初始化以下类:

public class MyClass
{
    public int Value1 { get; set; }
    public int[] Value2 { get; set; }
}

使用ConfigureServicesStartup.cs方法中的以下代码从配置初始化此类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddOptions();

    services.Configure<MyClass>(Configuration.GetSection("MyClass"));
    services.AddSingleton<AService>();

    services.AddMvc();
}

我的服务构造函数如下所示:

public FeedbackRetrievalService(IOptions<MyClass> myclass)
{
    _myclass = myclass;
}

在构造函数中,我注意到Value2null,即使它确实在配置中显示为空列表 - 这是我希望初始化属性的值。我预计只有在配置中缺少字段时才会使用null初始化该属性。有没有办法将字段初始化为空列表?

1 个答案:

答案 0 :(得分:8)

问题是JSON配置 loader 和配置 binder 是两个独立的组件。加载配置时,配置提供程序会将整个配置文件加载到键/值结构中,其中键是属性路径。在您的示例中,MyClass:Value2:0MyClass:Value2:1可以是Value2 JSON数组中两个数组元素的路径。

然后,配置 binder 将解释该结构并将其转换为您的类的对象。那时,它只会提供先前加载的键/值结构中可用的信息。

现在,如果在绑定之前查看加载的配置,您会注意到一个空数组不会产生任何结果。如果你考虑路径是如何工作的,那就有意义了:MyClass:Value2:0MyClass:Value2:1分别是Value2数组的索引0和1的值。但是如何为空数组工作?根本没有空数组的条目。

因此,由于空数组未出现在已加载的配置中,因此绑定器无法初始化数组。

然而,您可以为绑定配置类型设置默认值:

public class MyClass
{
    public int Value1 { get; set; }
    public int[] Value2 { get; set; } = Array.Empty<int>();
}

现在,如果将配置与该空数组绑定到该类型,则绑定程序将永远不会触及Value2,保留其默认值。