繁体   English   中英

绑定到 appsettings.json 中的空数组时为空属性

[英]Null property when binding to empty array in appsettings.json

我在使用Options模式时偶然发现了一个问题,其中模型属性在绑定到一个空的 JSON 数组时被设置为null

appsettings.json

{
  "MyOptions": {
    "Values": []
  }
}

我的选项.cs

public sealed class MyOptions
{
  public IEnumerable<string> Values { get; set; }
}

启动.cs

...
services.Configure<MyOptions>(                            
  _configuration.GetSection(nameof(MyOptions));
...

上述配置成功构建并在需要时注入IOptions<MyOptions> ,但是Values属性设置为null而不是空的可枚举。 这将导致以下代码抛出NullReferenceException

public class MyService
{
  public MyService(IOptions<MyOptions> options)
  {
    var values = options.Value.Values;

    foreach (var val in values)
    {
      // Do something
    }
  }
}

这已作为 dotnet 存储库 ( https://github.com/dotnet/extensions/issues/1341 ) 上的一个问题提出,尽管 MS 似乎已将其关闭为“按设计工作”。

是否有防止抛出NullReferenceException的解决方法?

一种可能的解决方法是更改MyOptions类以使用支持字段而不是自动属性,并在 getter 中使用空合并运算符返回空IEnumerable

public sealed class MyOptions
{
  private IEnumerable<string> _values;

  public IEnumerable<string> Values
  {
    get => _values ?? new List<string>();
    set => _values = value;
  }
}

我总是确保我在配置类中的属性分配了有意义的默认值:

public sealed class MyOptions
{
  public IEnumerable<string> Values { get; set; } = Array.Empty<string>();
}

这样我就不必在每次使用我的配置对象时检查null或未配置的值。

我认为 MS 给出了“按设计工作”的正确答案。 你一直都记得墨菲定律——任何可能出错的事情都会出错。 为了创建健壮的代码,任何人都应该期望任何可空属性的空值,不管它是如何初始化的。 它总是可以在途中的某个地方变为空。 所以我总是检查 null

  if (options.Value.Values != null)
    foreach (var val in options.Value.Values)
    {
       // Do something
    } else ... return error;
       

我不知道 myoptions 对这个应用程序有多重要,但我通常已经在启动时检查 appdata 数据

var myOptions = Configuration.GetSection(nameof(MyOptions));
if (myOptions.Exists())
{
    services.Configure<MyOptions>(myOptions);
    services.AddScoped(typeof(MyService));
} else ... return error

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM