【问题标题】:ASP.NET Core Json Configuration - Missing key value pair for an empty arrayASP.NET Core Json 配置 - 缺少空数组的键值对
【发布时间】:2018-07-18 11:13:51
【问题描述】:

给定如下json配置文件some_settings.json

{
    "AnEmptyArray": [],
    "APopulatedArray": [1, 2, 3]
}

作为源添加到 asp.net 核心配置系统并请求所有密钥时

var configuration = new ConfigurationBuilder()
    .AddJsonFile("some_settings.json")
    .Build();

var keys = configuration
    .AsEnumerable()
    .Select(c => c.Key);

结果是

APopulatedArray 
APopulatedArray:2 
APopulatedArray:1 
APopulatedArray:0 

由于某种原因,AnEmptyArray 没有密钥

如果我从 json 中完全删除 AnEmptyArray 键,结果是一样的

{
    "APopulatedArray": [1, 2, 3]
}

这意味着无法检测空数组和根本没有提供的数组之间的差异。

这对吗?

【问题讨论】:

  • 为什么当你通过 1,2,3 时得到 2,1,0 ?问题中的所有数据都正确吗?
  • 它们是数组索引,与值无关。这就是配置系统命名数组键的方式。

标签: asp.net asp.net-core configuration


【解决方案1】:

这意味着无法检测到 空数组并且根本没有提供数组。

这对吗?

如果很快 - 是的。

要了解原因,我们应该深入研究 .Net Core 配置加载机制。添加每个新源,例如AddJsonFile()AddEnvironmentVariables(),实际上将IConfigurationSource 的另一个实例广告到IConfigurationBuilder。当你最终调用IConfigurationBuilder.Build() 方法时,你会得到IConfigurationRoot 的实例,它本质上是一个已加载配置提供程序列表的持有者:

public interface IConfigurationRoot : IConfiguration
{
    IEnumerable<IConfigurationProvider> Providers { get; }
    void Reload();
}

更进一步,IConfigurationProvider 仅使用配置键值对操作:

public interface IConfigurationProvider
{
    IEnumerable<string> GetChildKeys(IEnumerable<string> earlierKeys, string parentPath);
    IChangeToken GetReloadToken();
    void Load();
    void Set(string key, string value);
    bool TryGet(string key, out string value);
}

IConfigurationProvider 根本不关心您设置的任何初始结构,例如数组或子部分:

这种机制有几个优点:

  1. 您可以在不同的来源中拥有不同的配置部分(即使是一个部分)。
  2. 您可以覆盖不同来源中某个部分的特定键值(保留部分的其他值)。

所以对您的问题的回答是“是”,您无法通过标准配置机制检测空数组和缺失数组之间的区别。初始 JSON 结构刚刚丢失,配置存储为键值对。空数组不会在IConfigurationProvider 中生成任何键值对。

【讨论】:

  • 但是为什么空数组不产生任何键值对呢?结果是我无法绑定一个空数组。这似乎是一个疏忽。
  • 您希望从空数组中获得什么键值? Array 产生像 Array:0, Array:1, ... Array 本身不是终端(叶)配置值,它只是进一步设置的持有者。 “我无法绑定空数组” - 如果您的 POCO 设置类具有数组属性,只需在构造函数中使用空数组对其进行初始化。配置活页夹将保持原样。结果你会得到空的设置数组。为什么这会导致问题?为什么需要为配置区分空数组和缺失数组?
  • 我正在配置系统之上构建自己的库。给定 POCO 设置,如果属性没有设置配置值以防止您添加属性但忘记在配置中设置它,则会引发异常。不幸的是,这个问题意味着对于数组,我无法判断是否提供了数组,因为空数组的处理方式与根本没有将其添加到配置中一样。
  • 您说的是 JSON。但考虑其他配置源,如环境变量、命令行、Azuer Key Vault 等。大多数配置源根本没有任何结构,并且在输入时使用键值对。如果您的配置完全从环境变量加载怎么办?在这种情况下,您会将变量 Array:0 之类的对设置为 Value。甚至没有办法输入空数组。因此,如果您希望您的库完全支持 .Net Core 配置惯用语,那么如果缺少某些设置,您不应该抛出异常。内置活页夹以这种方式工作。你应该跟随。
猜你喜欢
  • 2020-06-04
  • 2020-10-21
  • 2021-05-11
  • 1970-01-01
  • 2012-11-05
  • 2017-05-26
  • 2018-03-11
  • 2019-01-07
  • 2018-05-23
相关资源
最近更新 更多