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

Posted

技术标签:

【中文标题】绑定到 appsettings.json 中的空数组时的空属性【英文标题】:Null property when binding to empty array in appsettings.json 【发布时间】:2021-12-01 04:54:53 【问题描述】:

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

appsettings.json


  "MyOptions": 
    "Values": []
  

MyOptions.cs

public sealed class MyOptions

  public IEnumerable<string> Values  get; set; 

Startup.cs

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

上述配置成功构建并在需要时注入IOptions&lt;MyOptions&gt;,但是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 被抛出的解决方法?

【问题讨论】:

【参考方案1】:

一种可能的解决方法是更改​​MyOptions 类以使用支持字段而不是自动属性,并在getter 中使用null-coalescing operator 来返回一个空的IEnumerable

public sealed class MyOptions

  private IEnumerable<string> _values;

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

【讨论】:

【参考方案2】:

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

public sealed class MyOptions

  public IEnumerable<string> Values  get; set;  = Array.Empty<string>();

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

【讨论】:

我更喜欢这种方法,它更干净。【参考方案3】:

我认为 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

【讨论】:

以上是关于绑定到 appsettings.json 中的空数组时的空属性的主要内容,如果未能解决你的问题,请参考以下文章

appsettings.json 值在 Azure Functions App V3 中未绑定

(新格式)Visual Studio 项目中的可选 appsettings.local.json

从 .NET Core 2 中的类中读取 appsettings.json

将 GridViewColumn 绑定到 List<EntityFrameworkCore's Entity> 中的空属性

.NET Core 应用程序中的 appsettings.json 与 appsettings.Environment.json

使用VS2017中的AWS无服务器应用程序读取appsettings.json文件