aspnet / Configuration

[Archived] Interfaces and providers for accessing configuration files. Project moved to https://github.com/aspnet/Extensions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

/// comments wrong: ConfigurationSection.Value docs are incomplete

Rick-Anderson opened this issue · comments

Copy from MicrosoftDocs/feedback#303 by @MV10

The docs state "Gets or sets the section value."

This is only accurate if GetSection is called on a key that has a single value. If GetSection actually returns a configuration section, then Value will be null and the GetChildren extension method should be used to iterate over configuration contents.

ConfigurationSection
ConfigurationSection.Value
IConfigurationSection
IConfigurationSection.Value

I'm pretty sure a sections can have children and a value at the same time

@MV10 if you can post a repo we'll reopen this.

@Rick-Anderson It's simple to reproduce. ASP.NET not required! 😛

https://github.com/MV10/issue_aspnet_813

For this sample config, only the foo key results in a non-null Value property. (I was surprised the array in the bar entry also produces a null Value.)

FWIW, there is shipping code that relies on this. I started looking at it when I noticed the Serilog config package uses it to decide whether it just read a value to supply to a method parameter, or a new config section to recursively process.

{
  "section": {
    "subsection": {
      "foo": "has_value",
      "bar": [ 1, 2, 3 ],
      "baz": [
        { "this": 1 },
        { "that": 2 }
      ]
    }
  }
}
    class Program
    {
        static IConfiguration cfg;

        static void Main(string[] args)
        {
            cfg = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile(path: "appsettings.json", optional: false)
                .Build();

            test("section");
            test("section:subsection"); 
            test("section:subsection:foo"); // non-null value
            test("section:subsection:bar");
            test("section:subsection:baz");

            Console.WriteLine("\nPress any key.");
            Console.ReadKey();
        }

        static void test(string key)
        {
            var section = cfg.GetSection(key);
            Console.WriteLine($"{key} value is null? {section.Value is null}");
        }
    }

While its true a single json file can't express both a value and a subsection, that's not a limitation of configuration in general. You can accomplish that via two json files, with a second one that sets "section:subsection = "value". ini files support this natively. You can also directly set configuration values programatically

@HaoK Of course! Very interesting. Thank you.