Retrieve sections from config.json in ASP.NET 5

Let’s say I have a config.json like this:

{
  "CustomSection": {
    "A": 1,
    "B": 2
  }
}

I know I can use an IConfiguration object to get specific settings, i.e., configuration.Get("CustomSection:A"), but can I grab the whole hierarchy (in any type – even a raw string would be fine)? When I try configuration.Get("CustomSection"), I get a null result, so I think this isn’t supported by default.

My use case is grabbing entire configuration dictionaries at once without having to grab each individual setting – some properties may not be known at compile time.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I have solved a similar problem where I wanted to bind the entire IConfigurationRoot or IConfigurationSection to a Dictionary. Here is an extension class:

public class ConfigurationExtensions
{
    public static Dictionary<string, string> ToDictionary(this IConfiguration config, bool stripSectionPath = true)
    {
        var data = new Dictionary<string, string>();
        var section = stripSectionPath ? config as IConfigurationSection : null;
        ConvertToDictionary(config, data, section);
        return data;
    }

    static void ConvertToDictionary(IConfiguration config, Dictionary<string, string> data = null, IConfigurationSection top = null)
    {
        if (data == null) data = new Dictionary<string, string>();
        var children = config.GetChildren();
        foreach (var child in children)
        {
            if (child.Value == null)
            {
                ConvertToDictionary(config.GetSection(child.Key), data);
                continue;
            }

            var key = top != null ? child.Path.Substring(top.Path.Length + 1) : child.Path;
            data[key] = child.Value;
        }
    }
}

And using the extension:

IConfigurationRoot config;
var data = config.ToDictionary();
var data = config.GetSection("CustomSection").ToDictionary();

There is an optional parameter (stripSectionPath) to either retain the full section key path or to strip the section path out, leaving a relative path.

var data = config.GetSection("CustomSection").ToDictionary(false);

Method 2

configuration.Get is for getting a value to get a section you need

IConfiguration mysection = configuration.GetConfigurationSection("SectionKey");

Method 3

I was able to load and bind multiple sub sections with unknown keys like this (the syntax has changed slightly since your post; I recommend keeping an eye on the github project and their unit tests to see how it is currently working):

var objectSections = Configuration.GetSection("CustomObjects").GetChildren();
var objects = objectSections.ToDictionary(x => x.Key, x =>
{
    var obj = new CustomObject();
    ConfigurationBinder.Bind(x, obj);
    return obj ;
});

Method 4

Edit: updating this answer for the 1.0 release of Core.

This is possible now if you use a strongly typed object, for example:

public class CustomSection 
{
   public int A {get;set;}
   public int B {get;set;}
}

//In Startup.cs
services.Configure<CustomSection>(Configuration.GetSection("CustomSection"));
//You can then inject an IOptions instance
public HomeController(IOptions<CustomSection> options) 
{
    var settings = options.Value;
}

Method 5

For a detailed explanation, see
https://dotnetcodr.com/2017/01/20/introduction-to-asp-net-core-part-3-the-configuration-file/

Below is an example from the site:

Config file has this:

"Languages": {
  ".NET": [ "C#", "VB.NET", "F#" ],
  "JVM": ["Java", "Scala", "Clojure"]
}

Load this configuration as follows:

IConfigurationSection languagesSection = configRoot.GetSection("Languages");
IEnumerable<IConfigurationSection> languagesSectionMembers = languagesSection.GetChildren();
Dictionary<string, List<string>> platformLanguages = new Dictionary<string, List<string>>();
foreach (var platform in languagesSectionMembers)
{
    List<string> langs = (from p in platform.GetChildren() select p.Value).ToList();
    platformLanguages[platform.Key] = langs;
}

Method 6

You can use the ConfigurationBinder and read everything as Dictionary<string, string>

Here are some test cases that you can use as example: https://github.com/aspnet/Configuration/blob/dev/test/Microsoft.Framework.Configuration.Binder.Test/ConfigurationCollectionBindingTests.cs


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x