Получить разделы из config.json в ASP.NET 5
Допустим, у меня есть config.json
как это:
{
"CustomSection": {
"A": 1,
"B": 2
}
}
Я знаю, что могу использовать IConfiguration
объект для получения определенных настроек, т. е. configuration.Get("CustomSection:A")
, но я могу взять всю иерархию (в любом типе - даже необработанная строка будет в порядке)? Когда я пытаюсь configuration.Get("CustomSection")
Я получаю null
результат, поэтому я думаю, что это не поддерживается по умолчанию.
Мой вариант использования - захват целых словарей конфигурации одновременно без необходимости брать каждый отдельный параметр - некоторые свойства могут быть неизвестны во время компиляции.
6 ответов
Изменить: обновление этого ответа для версии 1.0 Core.
Теперь это возможно, если вы используете строго типизированный объект, например:
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;
}
Я решил аналогичную проблему, когда хотел связать весь IConfigurationRoot или IConfigurationSection со словарем. Вот класс расширения:
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;
}
}
}
И используя расширение:
IConfigurationRoot config;
var data = config.ToDictionary();
var data = config.GetSection("CustomSection").ToDictionary();
Существует необязательный параметр (stripSectionPath), чтобы либо сохранить полный путь ключа раздела, либо убрать путь раздела, оставляя относительный путь.
var data = config.GetSection("CustomSection").ToDictionary(false);
configuration.Get предназначен для получения значения, чтобы получить нужный вам раздел
IConfiguration mysection = configuration.GetConfigurationSection("SectionKey");
Мне удалось загрузить и связать несколько подразделов с неизвестными ключами, как это (синтаксис немного изменился со времени вашего поста; я рекомендую следить за проектом github и его модульными тестами, чтобы увидеть, как он работает в настоящее время):
var objectSections = Configuration.GetSection("CustomObjects").GetChildren();
var objects = objectSections.ToDictionary(x => x.Key, x =>
{
var obj = new CustomObject();
ConfigurationBinder.Bind(x, obj);
return obj ;
});
Для подробного объяснения см. https://dotnetcodr.com/2017/01/20/introduction-to-asp-net-core-part-3-the-configuration-file/
Ниже приведен пример с сайта:
Файл конфигурации имеет это:
"Languages": {
".NET": [ "C#", "VB.NET", "F#" ],
"JVM": ["Java", "Scala", "Clojure"]
}
Загрузите эту конфигурацию следующим образом:
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;
}
Вы можете использовать ConfigurationBinder
и читать все как Dictionary<string, string>
Вот несколько тестовых примеров, которые вы можете использовать в качестве примера: https://github.com/aspnet/Configuration/blob/dev/test/Microsoft.Framework.Configuration.Binder.Test/ConfigurationCollectionBindingTests.cs