ASP.NET Core Получить массив Json с помощью IConfiguration

168

В appsettings.json

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}

В Startup.cs

public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton<IConfiguration>(Configuration);
}

В HomeController

public class HomeController : Controller
{
    private readonly IConfiguration _config;
    public HomeController(IConfiguration config)
    {
        this._config = config;
    }

    public IActionResult Index()
    {
        return Json(_config.GetSection("MyArray"));
    }
}

Есть мои коды выше, я получил NULL Как получить массив?

Максимум
источник

Ответы:

103

Если вы хотите выбрать стоимость первого предмета, вы должны сделать следующее:

var item0 = _config.GetSection("MyArray:0");

Если вы хотите выбрать значение всего массива, вы должны сделать так:

IConfigurationSection myArraySection = _config.GetSection("MyArray");
var itemArray = myArraySection.AsEnumerable();

В идеале, вы должны рассмотреть возможность использования шаблона параметров, предложенного официальной документацией. Это даст вам больше преимуществ.

Sanket
источник
23
Если у вас есть массив объектов вроде "Clients": [ {..}, {..} ], вы должны вызвать Configuration.GetSection("Clients").GetChildren().
Halllo
40
Если у вас есть массив литералов вроде "Clients": [ "", "", "" ], вы должны вызвать .GetSection("Clients").GetChildren().ToArray().Select(c => c.Value).ToArray().
Halllo
6
Этот ответ на самом деле даст 4 элемента, первый из которых - сам раздел с пустым значением. Это неверно.
Джованни Басси
4
Я успешно призываю это так:var clients = Configuration.GetSection("Clients").GetChildren() .Select(clientConfig => new Client { ClientId = clientConfig["ClientId"], ClientName = clientConfig["ClientName"], ... }) .ToArray();
Halllo
1
Ни одна из этих опций не работает для меня, так как объект возвращается к нулю в точке «Клиенты», используя пример hallo. Я уверен, что JSON хорошо сформирован, поскольку он работает со смещением, вставленным в строку ["item: 0: childItem"] в формате "Item": [{...}, {...}]
Clarence
283

Вы можете установить следующие два пакета NuGet:

Microsoft.Extensions.Configuration    
Microsoft.Extensions.Configuration.Binder

И тогда у вас будет возможность использовать следующий метод расширения:

var myArray = _config.GetSection("MyArray").Get<string[]>();
Разван Думитру
источник
13
Это гораздо проще, чем другие ответы.
Джао
14
Это лучший ответ на сегодняшний день.
Джованни Басси
15
В моем случае, веб-приложение Aspnet core 2.1 включало эти два пакета nuget. Так что это была только одна строка изменения. Спасибо
Шибу Танниккуннатх,
Самый простой!
Пабло
3
Он также работает с массивом объектов, например _config.GetSection("AppUser").Get<AppUser[]>();
Giorgos Betsos
60

Добавьте уровень в ваш appsettings.json:

{
  "MySettings": {
    "MyArray": [
      "str1",
      "str2",
      "str3"
    ]
  }
}

Создайте класс, представляющий ваш раздел:

public class MySettings
{
     public List<string> MyArray {get; set;}
}

В своем классе запуска приложения свяжите свою модель и внедрите ее в службу DI:

services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));

И в вашем контроллере получите данные конфигурации из службы DI:

public class HomeController : Controller
{
    private readonly List<string> _myArray;

    public HomeController(IOptions<MySettings> mySettings)
    {
        _myArray = mySettings.Value.MyArray;
    }

    public IActionResult Index()
    {
        return Json(_myArray);
    }
}

Вы также можете сохранить всю свою конфигурационную модель в свойстве контроллера, если вам нужны все данные:

public class HomeController : Controller
{
    private readonly MySettings _mySettings;

    public HomeController(IOptions<MySettings> mySettings)
    {
        _mySettings = mySettings.Value;
    }

    public IActionResult Index()
    {
        return Json(_mySettings.MyArray);
    }
}

Служба внедрения зависимостей в ядре ASP.NET работает как шарм :)

AdrienTorris
источник
Так как вы используете MySettingsпри запуске?
Т.Кутлакис
Я получаю сообщение об ошибке, что ему нужна запятая между «MySettings» и «MyArray».
Маркус
35

Если у вас есть массив сложных объектов JSON, например:

{
  "MySettings": {
    "MyValues": [
      { "Key": "Key1", "Value":  "Value1" },
      { "Key": "Key2", "Value":  "Value2" }
    ]
  }
}

Вы можете получить настройки следующим образом:

var valuesSection = configuration.GetSection("MySettings:MyValues");
foreach (IConfigurationSection section in valuesSection.GetChildren())
{
    var key = section.GetValue<string>("Key");
    var value = section.GetValue<string>("Value");
}
Дмитрий Павлов
источник
30

Это сработало для меня, чтобы вернуть массив строк из моей конфигурации:

var allowedMethods = Configuration.GetSection("AppSettings:CORS-Settings:Allow-Methods")
    .Get<string[]>();

Мой раздел конфигурации выглядит так:

"AppSettings": {
    "CORS-Settings": {
        "Allow-Origins": [ "http://localhost:8000" ],
        "Allow-Methods": [ "OPTIONS","GET","HEAD","POST","PUT","DELETE" ]
    }
}
CodeThief
источник
15

Для случая возврата массива сложных объектов JSON из конфигурации я адаптировал ответ @ djangojazz для использования анонимных типов и динамических, а не кортежей.

Учитывая раздел настроек:

"TestUsers": [
{
  "UserName": "TestUser",
  "Email": "Test@place.com",
  "Password": "P@ssw0rd!"
},
{
  "UserName": "TestUser2",
  "Email": "Test2@place.com",
  "Password": "P@ssw0rd!"
}],

Вы можете вернуть массив объектов следующим образом:

public dynamic GetTestUsers()
{
    var testUsers = Configuration.GetSection("TestUsers")
                    .GetChildren()
                    .ToList()
                    .Select(x => new {
                        UserName = x.GetValue<string>("UserName"),
                        Email = x.GetValue<string>("Email"),
                        Password = x.GetValue<string>("Password")
                    });

    return new { Data = testUsers };
}
jaycer
источник
Это
Владимир
11

Вроде старый вопрос, но я могу дать обновленный ответ для .NET Core 2.1 со стандартами C # 7. Скажем, у меня есть список только в appsettings.Development.json, например:

"TestUsers": [
  {
    "UserName": "TestUser",
    "Email": "Test@place.com",
    "Password": "P@ssw0rd!"
  },
  {
    "UserName": "TestUser2",
    "Email": "Test2@place.com",
    "Password": "P@ssw0rd!"
  }
]

Я могу извлечь их в любом месте, где Microsoft.Extensions.Configuration.IConfiguration реализована и подключена следующим образом:

var testUsers = Configuration.GetSection("TestUsers")
   .GetChildren()
   .ToList()
    //Named tuple returns, new in C# 7
   .Select(x => 
         (
          x.GetValue<string>("UserName"), 
          x.GetValue<string>("Email"), 
          x.GetValue<string>("Password")
          )
    )
    .ToList<(string UserName, string Email, string Password)>();

Теперь у меня есть список хорошо напечатанных объектов. Если я перехожу к testUsers.First (), Visual Studio теперь должна отображать параметры для «UserName», «Email» и «Password».

djangojazz
источник
9

В ASP.NET Core 2.2 и более поздних версиях мы можем внедрить IConfiguration в любом месте нашего приложения, как в вашем случае, вы можете внедрить IConfiguration в HomeController и использовать его для получения массива.

string[] array = _config.GetSection("MyArray").Get<string[]>();
Сэнди
источник
5

Вы можете получить массив напрямую без приращения нового уровня в конфигурации:

public void ConfigureServices(IServiceCollection services) {
    services.Configure<List<String>>(Configuration.GetSection("MyArray"));
    //...
}
Андреас Фридель
источник
4

Короткая форма:

var myArray= configuration.GetSection("MyArray")
                        .AsEnumerable()
                        .Where(p => p.Value != null)
                        .Select(p => p.Value)
                        .ToArray();

Возвращает массив строк:

{ "Str1", "str2", "str3"}

мойтаба карими
источник
1
Работал на меня. Спасибо. Использование Microsoft.Extensions.Configuration.Binder тоже работает, однако я бы хотел не ссылаться на другой пакет Nuget, если единственная строка кода может выполнить эту работу.
Sau001
3

Это сработало для меня; Создайте некоторый файл JSON:

{
    "keyGroups": [
        {
            "Name": "group1",
            "keys": [
                "user3",
                "user4"
            ]
        },
        {
            "Name": "feature2And3",
            "keys": [
                "user3",
                "user4"
            ]
        },
        {
            "Name": "feature5Group",
            "keys": [
                "user5"
            ]
        }
    ]
}

Затем определите некоторый класс, который отображает:

public class KeyGroup
{
    public string name { get; set; }
    public List<String> keys { get; set; }
}

Пакеты Nuget:

Microsoft.Extentions.Configuration.Binder 3.1.3
Microsoft.Extentions.Configuration 3.1.3
Microsoft.Extentions.Configuration.json 3.1.3

Затем загрузите его:

using Microsoft.Extensions.Configuration;
using System.Linq;
using System.Collections.Generic;

ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

configurationBuilder.AddJsonFile("keygroup.json", optional: true, reloadOnChange: true);

IConfigurationRoot config = configurationBuilder.Build();

var sectionKeyGroups = 
config.GetSection("keyGroups");
List<KeyGroup> keyGroups = 
sectionKeyGroups.Get<List<KeyGroup>>();

Dictionary<String, KeyGroup> dict = 
            keyGroups = keyGroups.ToDictionary(kg => kg.name, kg => kg);
Роланд Роос
источник