kimsagro
kimsagro

Reputation: 17395

ASP.NET Core Json Configuration - Missing key value pair for an empty array

Given the following json configuration file some_settings.json

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

When adding as a source to the asp.net core configuration system and requesting all the keys

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

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

The results are

APopulatedArray 
APopulatedArray:2 
APopulatedArray:1 
APopulatedArray:0 

For some reason, there is no key for AnEmptyArray

The results are the same if I remove the AnEmptyArray key completly from the json

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

This means there is no way of detecting the difference between an empty array and the array not being provided at all.

Is this correct?

Upvotes: 1

Views: 1735

Answers (1)

CodeFuller
CodeFuller

Reputation: 31312

This means there is no way of detecting the difference between an empty array and the array not being provided at all.

Is this correct?

If shortly - yes.

To understand the reason, we should dig into the .Net Core configuration loading mechanism. Adding every new source, like AddJsonFile() or AddEnvironmentVariables(), actually ads another instance of IConfigurationSource to IConfigurationBuilder. When you finally call IConfigurationBuilder.Build() method, you get instance of IConfigurationRoot, which is essentially a holder for a list of loaded configuration providers:

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

Goring further, IConfigurationProvider operates only with configuration key-values pairs:

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 does not care at all about any initial structure of your settings, like arrays or sub-sections:

enter image description here

Such mechanism has several advantages:

  1. You could have different parts of configuration (even for one section) in different sources.
  2. You could override specific key values of a section (keeping other values for a section) in a different source.

So answer to your question is "Yes", you can't detect the difference between an empty array and missing array through standard configuration mechanism. Initial JSON structure is just lost and configuration is stored as key-value pairs. Empty arrays does not produce any key-value pair in IConfigurationProvider.

Upvotes: 1

Related Questions