Retrieve sections from config.json in ASP.NET 5

喜你入骨 提交于 2019-12-01 18:36:25

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);

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

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

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 ;
});

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;
}

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

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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!