ASP.NET Core Pobierz tablicę Json przy użyciu IConfiguration

168

W pliku appsettings.json

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

W Startup.cs

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

W HomeController

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

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

Powyżej znajdują się moje kody, mam null Jak pobrać tablicę?

Maks
źródło

Odpowiedzi:

103

Jeśli chcesz wybrać wartość pierwszego przedmiotu, powinieneś zrobić to:

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

Jeśli chcesz wybrać wartość całej tablicy, powinieneś zrobić to:

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

Najlepiej byłoby rozważyć użycie wzorca opcji sugerowanego w oficjalnej dokumentacji. Zapewni to więcej korzyści.

Sanket
źródło
23
Jeśli masz tablicę obiektów, takich jak "Clients": [ {..}, {..} ], powinieneś wywołać Configuration.GetSection("Clients").GetChildren().
halllo
40
Jeśli masz tablicę literałów, takich jak "Clients": [ "", "", "" ], powinieneś wywołać .GetSection("Clients").GetChildren().ToArray().Select(c => c.Value).ToArray().
halllo
6
Ta odpowiedź w rzeczywistości da 4 pozycje, z których pierwsza to sama sekcja z pustą wartością. To jest niepoprawne.
Giovanni Bassi
4
Z powodzeniem var clients = Configuration.GetSection("Clients").GetChildren() .Select(clientConfig => new Client { ClientId = clientConfig["ClientId"], ClientName = clientConfig["ClientName"], ... }) .ToArray();
wywołuję
1
Żadna z tych opcji nie działa dla mnie, ponieważ obiekt wraca do wartości zerowej w punkcie „Klienci” na przykładzie hallo. Jestem przekonany, że plik json jest dobrze sformułowany, ponieważ działa z przesunięciem wstawionym w ciągu ["item: 0: childItem"] w formacie "Item": [{...}, {...}]
Clarence
283

Możesz zainstalować następujące dwa pakiety NuGet:

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

Następnie będziesz mieć możliwość skorzystania z następującej metody rozszerzenia:

var myArray = _config.GetSection("MyArray").Get<string[]>();
Razvan Dumitru
źródło
13
Jest to o wiele prostsze niż inne odpowiedzi.
jao
14
To zdecydowanie najlepsza odpowiedź.
Giovanni Bassi
15
W moim przypadku aplikacja internetowa Aspnet core 2.1 zawierała te dwa pakiety NuGet. Więc to była tylko jedna zmiana linii. Dzięki
Shibu Thannikkunnath
Najprostszy!
Pablo
3
Działa również z szeregiem obiektów, np. _config.GetSection("AppUser").Get<AppUser[]>();
Giorgos Betsos
60

Dodaj poziom w pliku appsettings.json:

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

Utwórz klasę reprezentującą Twoją sekcję:

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

W klasie startowej aplikacji powiąż model i wstrzyknij go do usługi DI:

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

W kontrolerze pobierz dane konfiguracyjne z usługi 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);
    }
}

Możesz również przechowywać cały model konfiguracji we właściwości w kontrolerze, jeśli potrzebujesz wszystkich danych:

public class HomeController : Controller
{
    private readonly MySettings _mySettings;

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

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

Usługa wstrzykiwania zależności ASP.NET Core działa jak urok :)

AdrienTorris
źródło
Jak więc używasz MySettingsw Startupie?
T.Coutlakis
Pojawia się błąd, że potrzebny jest przecinek między „MySettings” a „MyArray”.
Markus
35

Jeśli masz tablicę złożonych obiektów JSON, taką jak ta:

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

Możesz pobrać ustawienia w ten sposób:

var valuesSection = configuration.GetSection("MySettings:MyValues");
foreach (IConfigurationSection section in valuesSection.GetChildren())
{
    var key = section.GetValue<string>("Key");
    var value = section.GetValue<string>("Value");
}
Dmitry Pavlov
źródło
30

Pomogło mi to zwrócić tablicę ciągów z mojej konfiguracji:

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

Moja sekcja konfiguracji wygląda następująco:

"AppSettings": {
    "CORS-Settings": {
        "Allow-Origins": [ "http://localhost:8000" ],
        "Allow-Methods": [ "OPTIONS","GET","HEAD","POST","PUT","DELETE" ]
    }
}
CodeThief
źródło
15

W przypadku zwracania tablicy złożonych obiektów JSON z konfiguracji, dostosowałem odpowiedź @ djangojazz tak, aby używała anonimowych typów i dynamicznych zamiast krotek.

Biorąc pod uwagę sekcję ustawień:

"TestUsers": [
{
  "UserName": "TestUser",
  "Email": "[email protected]",
  "Password": "P@ssw0rd!"
},
{
  "UserName": "TestUser2",
  "Email": "[email protected]",
  "Password": "P@ssw0rd!"
}],

Możesz zwrócić tablicę obiektów w ten sposób:

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
źródło
To jest niesamowite
Vladimir Demirev
11

Niby stare pytanie, ale mogę udzielić odpowiedzi zaktualizowanej dla .NET Core 2.1 ze standardami C # 7. Powiedzmy, że mam listę tylko w appsettings.Development.json, na przykład:

"TestUsers": [
  {
    "UserName": "TestUser",
    "Email": "[email protected]",
    "Password": "P@ssw0rd!"
  },
  {
    "UserName": "TestUser2",
    "Email": "[email protected]",
    "Password": "P@ssw0rd!"
  }
]

Mogę je wyodrębnić wszędzie tam, gdzie Microsoft.Extensions.Configuration.IConfiguration jest zaimplementowana i okablowana w następujący sposób:

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

Teraz mam listę dobrze wpisanego obiektu, który jest dobrze wpisany. Jeśli przejdę do testuUsers.First (), program Visual Studio powinien teraz wyświetlać opcje dla „Nazwa użytkownika”, „E-mail” i „Hasło”.

djangojazz
źródło
9

W ASP.NET Core 2.2 i nowszych możemy wstrzyknąć IConfiguration w dowolnym miejscu w naszej aplikacji, tak jak w twoim przypadku, możesz wstrzyknąć IConfiguration w HomeController i użyć w ten sposób, aby uzyskać tablicę.

string[] array = _config.GetSection("MyArray").Get<string[]>();
piaszczysty
źródło
5

Możesz uzyskać tablicę bezpośrednio bez zwiększania nowego poziomu w konfiguracji:

public void ConfigureServices(IServiceCollection services) {
    services.Configure<List<String>>(Configuration.GetSection("MyArray"));
    //...
}
Andreas Friedel
źródło
4

Skrócona forma:

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

Zwraca tablicę ciągów:

{"słowo1", "słowo2", "słowo3"}

mojtaba karimi
źródło
1
Pracował dla mnie. Dzięki. Używanie Microsoft.Extensions.Configuration.Binder działa również, jednak chciałbym trzymać się z daleka od odwoływania się do innego pakietu Nuget, jeśli pojedyncza linia kodu może wykonać zadanie.
Sau001
3

To zadziałało dla mnie; Utwórz plik json:

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

Następnie zdefiniuj klasę, która odwzorowuje:

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

pakiety nuget:

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

Następnie załaduj go:

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);
Roland Roos
źródło