Konfiguracja w aplikacji ASP.NET Core

Autorzy: Rick Anderson i Kirk Larkin

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Konfiguracja aplikacji na platformie ASP.NET Core jest przeprowadzana przy użyciu co najmniej jednego dostawcy konfiguracji. Dostawcy konfiguracji odczytują dane konfiguracji z par klucz-wartość przy użyciu różnych źródeł konfiguracji:

  • Pliki ustawień, takie jak appsettings.json
  • Zmienne środowiskowe
  • Azure Key Vault
  • Azure App Configuration
  • Argumenty wiersza polecenia
  • Dostawcy niestandardowi, zainstalowani lub utworzeni
  • Pliki katalogów
  • Obiekty platformy .NET w pamięci

Ten artykuł zawiera informacje na temat konfiguracji na platformie ASP.NET Core. Aby uzyskać informacje na temat używania konfiguracji w aplikacjach konsoli, zobacz artykuł dotyczący konfiguracji platformy .NET.

Aplikacja i konfiguracja hosta

Aplikacje ASP.NET Core konfigurują i uruchamiają hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Szablony ASP.NET Core umożliwiają tworzenie obiektu WebApplicationBuilder zawierającego host. Chociaż niektóre konfiguracje można wykonać zarówno na hoście, jak i w obrębie dostawców konfiguracji aplikacji, mówiąc ogólnie, tylko konfiguracja niezbędna w przypadku hosta powinna być przeprowadzana w ramach konfiguracji hosta.

Konfiguracja aplikacji ma najwyższy priorytet i została szczegółowo opisana w kolejnej sekcji. Konfiguracja hosta następuje po konfiguracji aplikacji i została opisana w tym artykule.

Domyślne źródła konfiguracji aplikacji

Aplikacje internetowe ASP.NET Core utworzone za pomocą platformy dotnet new lub programu Visual Studio generują następujący kod:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder inicjuje nowe wystąpienie klasy WebApplicationBuilder ze wstępnie skonfigurowanymi wartościami domyślnymi. Zainicjowane narzędzie WebApplicationBuilder (builder) zapewnia domyślną konfigurację aplikacji w następującej kolejności, od priorytetu najwyższego do najniższego:

  1. Argumenty wiersza polecenia, które korzystają z dostawcy konfiguracji wiersza polecenia.
  2. Zmienne środowiskowe bez prefiksu, które korzystają z dostawcy konfiguracji zmiennych środowiskowych bez prefiksu.
  3. Wpisy tajne użytkownika w przypadku aplikacji działającej w środowisku Development.
  4. Element appsettings.{Environment}.json korzystający z dostawcy konfiguracji JSON. Przykład: appsettings.Production.json i appsettings.Development.json.
  5. Plik appsettings.json korzystający z dostawcy konfiguracji JSON.
  6. Alternatywa konfiguracji hosta opisanej w następnej sekcji.

Domyślne źródła konfiguracji hosta

Poniższa lista zawiera domyślne źródła konfiguracji hosta z najwyższego do najniższego priorytetu dla programu WebApplicationBuilder:

  1. Argumenty wiersza polecenia korzystające z dostawcy konfiguracji wiersza polecenia
  2. Zmienne środowiskowe z prefiksem DOTNET_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  3. Zmienne środowiskowe z prefiksem ASPNETCORE_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.

W przypadku hosta ogólnego platformy .NET i hosta sieci Web domyślne źródła konfiguracji hosta z najwyższego do najniższego priorytetu to:

  1. Zmienne środowiskowe z prefiksem ASPNETCORE_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  2. Argumenty wiersza polecenia korzystające z dostawcy konfiguracji wiersza polecenia
  3. Zmienne środowiskowe z prefiksem DOTNET_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.

Jeśli wartość konfiguracji zostanie ustawiona w konfiguracji hosta i aplikacji, będzie używana konfiguracja aplikacji.

Zmienne hosta

Następujące zmienne są blokowane na wczesnym etapie inicjowania konstruktorów hostów i konfiguracja aplikacji nie może mieć na nie wpływu:

Wszystkie pozostałe ustawienia hosta są odczytywane z konfiguracji aplikacji zamiast z konfiguracji hosta.

URLS to jedno z wielu typowych ustawień hosta, które nie jest związane z uruchomieniem. Podobnie jak wszystkie inne ustawienia hosta, których nie ma na liście, ustawienie URLS jest odczytywane później z konfiguracji aplikacji. Konfiguracja hosta to alternatywa konfiguracji aplikacji, więc konfiguracja hosta może służyć do ustawienia elementu URLS, ale zostanie zastąpiona przez dowolne źródło konfiguracji aplikacji, takie jak appsettings.json.

Aby uzyskać więcej informacji, zobacz sekcje Zmienianie katalogu głównego zawartości, nazwy aplikacji i środowiska i Zmienianie katalogu głównego zawartości, nazwy aplikacji i środowiska przy użyciu zmiennych środowiskowych lub wiersza polecenia

Pozostałe sekcje tego artykułu dotyczą konfiguracji aplikacji.

Dostawcy konfiguracji aplikacji

Poniższy kod powoduje wyświetlenie włączonych dostawców konfiguracji w kolejności, w której zostali dodani:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

Poprzednia lista domyślnych źródeł konfiguracji uporządkowanych w kolejności priorytetów od najwyższego do najniższego zawiera dostawców w odwrotnej kolejności, w której są oni dodawani do aplikacji wygenerowanej za pomocą szablonu. Na przykład dostawca konfiguracji JSON jest dodawany przed dostawcą konfiguracji wiersza polecenia.

Dostawcy konfiguracji dodani później mają wyższy priorytet i zastępują poprzednie ustawienia klucza. Jeśli na przykład element MyKey zostanie ustawiony w elemencie appsettings.json i środowisku, będzie używana wartość środowiska. Przy użyciu domyślnych dostawców konfiguracji dostawca konfiguracji wiersza polecenia zastępuje wszystkich innych dostawców.

Aby uzyskać więcej informacji na temat elementu CreateBuilder, zapoznaj się z sekcją Domyślne ustawienia konstruktora.

appsettings.json

Rozważ użycie następującego pliku appsettings.json:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Domyślny element JsonConfigurationProvider powoduje załadowanie konfiguracji w następującej kolejności:

  1. appsettings.json
  2. appsettings.{Environment}.json: na przykład pliki appsettings.Production.json i appsettings.Development.json. Wersja środowiska pliku jest ładowana w oparciu o element IHostingEnvironment.EnvironmentName. Więcej informacji można znaleźć w temacie Używanie wielu środowisk na platformie ASP.NET Core.

Wartości appsettings.{Environment}.json zastępują klucze w pliku appsettings.json. Na przykład domyślnie:

  • W środowisku tworzenia konfiguracja appsettings.Development.json zastępuje wartości znalezione w pliku appsettings.json.
  • W środowisku produkcyjnym konfiguracja appsettings.Production.json zastępuje wartości znalezione w pliku appsettings.json. Na przykład w przypadku wdrażania aplikacji na platformie Azure.

Jeśli wartość konfiguracji musi być gwarantowana, zobacz GetValue. W poprzednim przykładzie odbywa się tylko odczytywanie ciągów, a wartość domyślna nie jest obsługiwana.

W przypadku korzystania z konfiguracji domyślnej włączane są pliki appsettings.json i appsettings.{Environment}.json z elementem reloadOnChange: true. Zmiany wprowadzone w plikach appsettings.json i appsettings.{Environment}.jsonpo uruchomieniu aplikacji są odczytywane przez dostawcę konfiguracji JSON.

Komentarze w appsettings.json

Komentarze w plikach appsettings.json i appsettings.{Environment}.json są obsługiwane przy użyciu komentarzy w stylu języka JavaScript lub C#.

Tworzenie powiązania hierarchicznych danych konfiguracji przy użyciu wzorca opcji

Preferowanym sposobem odczytywania powiązanych wartości konfiguracji jest użycie wzorca opcji. Aby na przykład odczytać następujące wartości konfiguracji:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

Utwórz następującą klasę PositionOptions:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

Klasa opcji:

  • Musi być nieabstrakcyjna z publicznym konstruktorem bez parametrów.
  • Wszystkie publiczne właściwości typu do odczytu i zapisu są powiązane.
  • Pola nie są powiązane. W poprzednim kodzie element Position nie jest powiązany. Dzięki użyciu pola Position ciąg "Position" nie musi być ustalony w aplikacji w przypadku tworzenia powiązania klasy z dostawcą konfiguracji.

Następujący kod powoduje:

  • Wywołanie elementu ConfigurationBinder.Bind w celu powiązania klasy PositionOptions z sekcją Position.
  • Wyświetlenie danych konfiguracji Position.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON są domyślnie odczytywane po uruchomieniu aplikacji.

Element ConfigurationBinder.Get<T> tworzy powiązanie i zwraca określony typ. Element ConfigurationBinder.Get<T> może być wygodniejszy w użyciu niż element ConfigurationBinder.Bind. W poniższym kodzie pokazano sposób użycia elementu ConfigurationBinder.Get<T> z klasą PositionOptions:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON są domyślnie odczytywane po uruchomieniu aplikacji.

Alternatywne podejście w przypadku korzystania z wzorca opcji to utworzenie powiązania sekcji Position i dodanie go do kontenera usługi wstrzykiwania zależności. W poniższym kodzie element PositionOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

Przy użyciu poprzedniego kodu następujący kod odczytuje opcje położenia:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON wprowadzone po uruchomieniu aplikacji nie są odczytywane. Aby odczytać zmiany po uruchomieniu aplikacji, użyj elementu IOptionsSnapshot.

W przypadku korzystania z konfiguracji domyślnej włączane są pliki appsettings.json i appsettings.{Environment}.json z elementem reloadOnChange: true. Zmiany wprowadzone w plikach appsettings.json i appsettings.{Environment}.jsonpo uruchomieniu aplikacji są odczytywane przez dostawcę konfiguracji JSON.

Zobacz opis dostawcy konfiguracji JSON w tym dokumencie, aby uzyskać informacje na temat dodawania kolejnych plików konfiguracji JSON.

Łączenie kolekcji usług

Rozważ użycie następujących elementów, które rejestrują usługi i konfigurują opcje:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

Powiązane grupy rejestracji można przenieść do metody rozszerzenia w celu zarejestrowania usług. Na przykład usługi konfiguracji są dodawane do następującej klasy:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

Pozostałe usługi są rejestrowane w podobnej klasie. Poniższy kod używa nowych metod rozszerzenia do rejestrowania usług:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

Uwaga: każda metoda rozszerzenia services.Add{GROUP_NAME} dodaje i potencjalnie konfiguruje usługi. Na przykład metoda AddControllersWithViews dodaje kontrolery MVC usług z wymaganymi widokami, a metoda AddRazorPages dodaje usługi wymagane przez usługę Razor Pages.

Zabezpieczenia i wpisy tajne użytkownika

Wytyczne dotyczące danych konfiguracji:

  • Nigdy nie przechowuj haseł ani innych poufnych danych w kodzie dostawcy konfiguracji ani w plikach konfiguracji w postaci zwykłego tekstu. Narzędzie Menedżer wpisów tajnych może służyć do przechowywania wpisów tajnych w środowisku tworzenia.
  • Nie używaj wpisów tajnych produkcji w środowiskach tworzenia ani testowania.
  • Określaj wpisy tajne poza projektem, aby nie można było ich przypadkowo zatwierdzić w repozytorium kodu źródłowego.

Domyślnie źródło konfiguracji wpisów tajnych użytkownika jest rejestrowane po źródłach konfiguracji JSON. Dlatego wpisy tajne użytkownika mają pierwszeństwo przed kluczami w plikach appsettings.json i appsettings.{Environment}.json.

Więcej informacji na temat przechowywania haseł i innych danych poufnych:

Azure Key Vault bezpiecznie przechowuje wpisy tajne aplikacji ASP.NET Core. Aby uzyskać więcej informacji, zobacz artykuł Dostawca konfiguracji usługi Azure Key Vault w ASP.NET Core.

Zmienne środowiskowe bez prefiksu

Zmienne środowiskowe bez prefiksów to zmienne środowiskowe inne niż zmienne z prefiksem ASPNETCORE_ lub DOTNET_. Jest to na przykład zestaw szablonów aplikacji internetowych platformy ASP.NET Core "ASPNETCORE_ENVIRONMENT": "Development" w pliku launchSettings.json. Aby uzyskać więcej informacji na temat zmiennych środowiskowych ASPNETCORE_ i DOTNET_, zobacz:

Używając konfiguracji domyślnej, element EnvironmentVariablesConfigurationProvider ładuje konfigurację z par klucz-wartość zmiennej środowiskowej po odczytaniu plików appsettings.json, appsettings.{Environment}.json oraz wpisów tajnych użytkownika. W związku z tym wartości kluczy odczytane ze środowiska zastępują wartości odczytane z plików appsettings.json, appsettings.{Environment}.json oraz wpisów tajnych użytkownika.

Separator : nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Symbol __ (podwójne podkreślenie):

  • Jest obsługiwany przez wszystkie platformy. Na przykład separator : nie jest obsługiwany przez powłokę Bash, a separator __ jest.
  • Jest automatycznie zastępowany przez :

Następujące polecenia set:

set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

Poprzednie ustawienia środowiska:

  • Są ustawiane tylko w procesach uruchamianych z okna poleceń, w których zostały ustawione.
  • Nie będą odczytywane przez przeglądarki uruchamiane przy użyciu programu Visual Studio.

Następujące polecenia setx służą do ustawiania kluczy i wartości środowiska w systemie Windows. W przeciwieństwie do polecenia set, ustawienia polecenia setx są trwałe. Element /M ustawia zmienną w środowisku systemowym. Jeśli przełącznik /M nie jest używany, ustawiana jest zmienna środowiskowa użytkownika.

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

Aby sprawdzić, czy poprzednie polecenia zastępują appsettings.json i appsettings.{Environment}.json:

  • Przy użyciu programu Visual Studio: zamknij i uruchom ponownie program Visual Studio.
  • Za pomocą interfejsu wiersza polecenia: uruchom nowe okno polecenia i wprowadź dotnet run.

Wywołaj polecenie AddEnvironmentVariables z ciągiem, aby określić prefiks zmiennych środowiskowych:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

Powyższy kod:

Prefiks jest usuwany podczas odczytu par klucz-wartość konfiguracji.

Następujące polecenia testują prefiks niestandardowy:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

Konfiguracja domyślna ładuje zmienne środowiskowe i argumenty wiersza polecenia poprzedzone prefiksami DOTNET_ i ASPNETCORE_. Prefiksy DOTNET_ i ASPNETCORE_ są używane na platformie ASP.NET Core na potrzeby konfiguracji hosta i aplikacji, ale nie na potrzeby konfiguracji użytkownika. Aby uzyskać więcej informacji na temat konfiguracji hosta i aplikacji, zobacz artykuł Host ogólny platformy .NET.

W usłudze Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Ustawienia > Konfiguracja. Ustawienia aplikacji usługi Azure App Service są:

  • szyfrowane podczas przechowywania i przesyłane za pośrednictwem zaszyfrowanego kanału,
  • Uwidaczniane jako zmienne środowiskowe.

Aby uzyskać więcej informacji, zobacz Azure Apps: zastępowanie konfiguracji aplikacji przy użyciu witryny Azure Portal.

Zobacz Prefiksy parametrów połączenia, aby uzyskać informacje na temat parametrów połączenia bazy danych platformy Azure.

Nazewnictwo zmiennych środowiskowych

Nazwy zmiennych środowiskowych odzwierciedlają strukturę pliku appsettings.json. Każdy element w hierarchii jest oddzielony podwójnym podkreśleniem (opcja preferowana) lub dwukropkiem. Jeśli struktura elementów zawiera tablicę, indeks tablicy powinien być traktowany jako dodatkowa nazwa elementu w tej ścieżce. Zapoznajmy się z następującym plikiem appsettings.json i jego równoważnymi wartości reprezentowanymi jako zmienne środowiskowe.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

zmienne środowiskowe

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

Zmienne środowiskowe ustawiane w wygenerowanym pliku launchSettings.json

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym. Na przykład szablony internetowe ASP.NET Core generują plik launchSettings.json, który ustawia konfigurację punktu końcowego na:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

Skonfigurowanie applicationUrl ustawia zmienną środowiskową ASPNETCORE_URLS i zastępuje wartości ustawione w środowisku.

Stosowanie opcji ucieczki w zmiennych środowiskowych w systemie Windows

W systemie Linux należy zastosować opcję ucieczki dla zmiennych środowiskowych URL, aby element systemd mógł je przeanalizować. Użyj narzędzia systemd-escape systemu Linux, które daje w wyniku http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

Wyświetlanie zmiennych środowiskowych

Poniższy kod wyświetla wartości i zmienne środowiskowe podczas uruchamiania aplikacji, co może być przydatne podczas debugowania ustawień środowiska:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

Wiersz polecenia

Używając konfiguracji domyślnej, element CommandLineConfigurationProvider ładuje konfigurację z par klucz-wartość argumentów wiersza polecenia po następujących źródłach konfiguracji:

  • Pliki appsettings.json i appsettings.{Environment}.json.
  • Wpisy tajne aplikacji w środowisku deweloperskim.
  • Zmienne środowiskowe.

Domyślnie wartości konfiguracji ustawione w wierszu polecenia zastępują wartości konfiguracji ustawione w ramach wszystkich innych dostawców konfiguracji.

Argumenty wiersza polecenia

Następujące polecenie ustawia klucze i wartości przy użyciu =:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

Następujące polecenie ustawia klucze i wartości przy użyciu /:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

Następujące polecenie ustawia klucze i wartości przy użyciu --:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

Wartość klucza:

  • Musi następować po = lub klucz musi mieć prefiks -- albo /, gdy wartość następuje po spacji.
  • Nie jest wymagana w przypadku użycia elementu =. Na przykład MySetting=.

W tym samym poleceniu nie mieszaj par klucz-wartość argumentu wiersza polecenia, które używają elementu =, z parami klucz-wartość, które używają spacji.

Mapowania przełączników

Mapowania przełączników umożliwiają stosowanie logiki zastępowania nazwy klucza. Udostępnij słownik zamienników przełączników metodzie AddCommandLine.

Jeśli używasz słownika mapowań przełączników, jest on sprawdzany pod kątem klucza zgodnego z kluczem dostarczonym przez argument wiersza polecenia. Po znalezieniu klucza wiersza polecenia w słowniku wartość ze słownika jest przekazywana z powrotem w celu ustawienia pary klucz-wartość w konfiguracji aplikacji. Mapowanie przełącznika jest wymagane dla dowolnego klucza wiersza polecenia poprzedzonego pojedynczym łącznikiem (-).

Reguły dotyczące kluczy słownika mapowania przełączników:

  • Przełączniki muszą zaczynać się od - lub --.
  • Słownik mapowań przełącznika nie może zawierać zduplikowanych kluczy.

Aby używać słownika mapowań przełączników, przekaż go do wywołania do AddCommandLine:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

Uruchom następujące polecenie, aby przetestować zamiennik klucza:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

Poniższy kod pokazuje wartości zastąpionych kluczy:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

W przypadku aplikacji korzystających z mapowań przełączników wywołanie do CreateDefaultBuilder nie powinno przekazywać argumentów. Wywołanie polecenia AddCommandLine w metodzie CreateDefaultBuilder nie uwzględnia mapowanych przełączników i nie ma sposobu na przekazanie słownika mapowań przełączników do CreateDefaultBuilder. Rozwiązaniem nie jest przekazanie argumentów do metody CreateDefaultBuilder, ale zezwolenie umożliwia metodzie AddCommandLine w metodzie ConfigurationBuilder przetwarzanie zarówno argumentów, jak i słownika mapowania przełączników.

Ustawianie argumentów środowiska i wiersza polecenia w programie Visual Studio

Argumenty środowiska i wiersza polecenia można ustawić w programie Visual Studio w oknie dialogowym profilów uruchamiania:

  • W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Właściwości.
  • Wybierz kartę Debugowanie > Ogólne i wybierz pozycję Otwórz interfejs użytkownika debugowania profilów uruchamiania.

Hierarchiczne dane konfiguracji

Interfejs API konfiguracji odczytuje hierarchiczne dane konfiguracji, spłaszczając dane hierarchiczne przy użyciu ogranicznika w kluczach konfiguracji.

Przykładowy materiał do pobrania zawiera następujący plik appsettings.json:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Poniższy kod z przykładowego materiału do pobrania powoduje wyświetlenie kilku ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Preferowanym sposobem odczytywania hierarchicznych danych konfiguracji jest użycie wzorca opcji. Aby uzyskać więcej informacji, zapoznaj się z sekcją Tworzenie powiązania hierarchicznych danych konfiguracji w tym dokumencie.

Metody GetSection i GetChildren są dostępne w przypadki izolowania sesji i elementów podrzędnych sekcji w danych konfiguracji. Te metody zostały dalej opisane w sekcji GetSection, GetChildren i Exists.

Klucze i wartości konfiguracji

Klucze konfiguracji:

  • Nie uwzględniają wielkości liter. Na przykład ConnectionString i connectionstring są traktowane jako klucze równoważne.
  • Jeśli klucz i wartość jest ustawiana w więcej niż jednym dostawcy konfiguracji, zostanie użyta wartość z ostatniego dodanego dostawcy. Aby uzyskać więcej informacji, zobacz Konfiguracja domyślna.
  • Klucze hierarchiczne
    • W interfejsie API konfiguracji separator w postaci dwukropka (:) działa na wszystkich platformach.
    • W zmiennych środowiskowych separator w postaci dwukropka może nie działać na wszystkich platformach. Podwójne podkreślenie (__) jest obsługiwane na wszystkich platformach i jest automatycznie konwertowane na dwukropek (:).
    • W usłudze Azure Key Vault klucze hierarchiczne używają separatora --. Dostawca konfiguracji usługi Azure Key Vault automatycznie zastępuje znak -- znakiem :, gdy wpisy tajne są ładowane do konfiguracji aplikacji.
  • Element ConfigurationBinder obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Tworzenie powiązań tablic jest opisane w sekcji Tworzenie powiązania tablicy z klasą.

Wartości konfiguracji:

  • Są ciągami.
  • Wartości null nie mogą być przechowywane w konfiguracji ani powiązane z obiektami.

Dostawcy konfiguracji

W poniższej tabeli przedstawiono dostawców konfiguracji dostępnych dla aplikacji platformy ASP.NET Core.

Dostawca Dostarcza konfigurację z
Dostawca konfiguracji usługi Azure Key Vault Azure Key Vault
Dostawca konfiguracji aplikacji platformy Azure Azure App Configuration
Dostawca konfiguracji wiersza polecenia Parametry wiersza polecenia
Niestandardowy dostawca konfiguracji Źródło niestandardowe
Dostawca konfiguracji zmiennych środowiskowych Zmienne środowiskowe
Dostawca konfiguracji plików Pliki INI, JSON i XML
Dostawca konfiguracji typu „klucz na plik” Pliki katalogów
Dostawca konfiguracji pamięci Kolekcje w pamięci
Wpisy tajne użytkownika Plik w katalogu profilów użytkownika

Źródła konfiguracji są odczytywane w kolejności, w której określono odpowiednich dostawców konfiguracji. Uporządkuj dostawców konfiguracji w kodzie, aby dopasować priorytety do bazowych źródeł konfiguracji, których wymaga aplikacja.

Typowa sekwencja dostawców konfiguracji to:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. Wpisy tajne użytkownika
  4. Zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  5. Argumenty wiersza polecenia, które korzystają z dostawcy konfiguracji wiersza polecenia.

Powszechną praktyką jest dodawanie dostawcy konfiguracji wiersza polecenia jako ostatniego w serii dostawców, aby zezwolić argumentom wiersza polecenia na zastępowanie konfiguracji ustawionych przez innych dostawców.

Poprzednia sekwencja dostawców jest używana w konfiguracji domyślnej.

Prefiksy parametrów połączenia

Interfejs API konfiguracji ma specjalne reguły przetwarzania dla czterech zmiennych środowiskowych parametrów połączenia. Te parametry połączenia są uwzględniane podczas konfigurowania parametrów połączenia platformy Azure dla środowiska aplikacji. Zmienne środowiskowe z prefiksami pokazanymi w tabeli są ładowane do aplikacji z użyciem konfiguracji domyślnej lub gdy prefiks nie zostanie dostarczony do elementu AddEnvironmentVariables.

Prefiks parametrów połączenia Dostawca
CUSTOMCONNSTR_ Dostawca niestandardowy
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

Gdy zmienna środowiskowa zostanie odnaleziona i załadowana do konfiguracji z dowolnym z czterech prefiksów pokazanych w tabeli:

  • Klucz konfiguracji jest tworzony przez usunięcie prefiksu zmiennej środowiskowej i dodanie sekcji klucza konfiguracji (ConnectionStrings).
  • Tworzona jest nowa para klucz-wartość konfiguracji, która reprezentuje dostawcę połączenia z bazą danych (z wyjątkiem elementu CUSTOMCONNSTR_, który nie ma podanego dostawcy).
Klucz zmiennej środowiskowej Przekonwertowany klucz konfiguracji Wpis konfiguracji dostawcy
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Wpis konfiguracji nie został utworzony.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: System.Data.SqlClient

Dostawca konfiguracji plików

FileConfigurationProvider to klasa bazowa na potrzeby ładowania konfiguracji z systemu plików. Następujący dostawcy konfiguracji pochodzą z obiektu FileConfigurationProvider:

Dostawca konfiguracji plików INI

Element IniConfigurationProvider ładuje konfigurację z par klucz-wartość pliku INI w czasie wykonywania.

Poniższy kod dodaje kilku dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

W poprzednim kodzie ustawienia w plikach MyIniConfig.ini i MyIniConfig.{Environment}.ini są zastępowane przez ustawienia w następujących obszarach:

Przykładowy materiał do pobrania zawiera następujący plik MyIniConfig.ini:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Dostawca konfiguracji plików JSON

Element JsonConfigurationProvider ładuje konfigurację z par klucz-wartość pliku JSON.

Przeciążenia mogą wskazywać, czy:

  • Plik jest opcjonalny.
  • Konfiguracja zostanie ponownie załadowana, jeśli plik się zmieni.

Spójrzmy na poniższy kod:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

Powyższy kod ma następujące działanie:

Zazwyczaj nie chcesz, aby niestandardowy plik JSON zastępował wartości ustawione w obrębie dostawcy konfiguracji zmiennych środowiskowych i dostawcy konfiguracji wiersza polecenia.

Dostawca konfiguracji plików XML

Element XmlConfigurationProvider ładuje konfigurację z par klucz-wartość pliku XML w czasie wykonywania.

Poniższy kod dodaje kilku dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

W poprzednim kodzie ustawienia w plikach MyXMLFile.xml i MyXMLFile.{Environment}.xml są zastępowane przez ustawienia w następujących obszarach:

Przykładowy materiał do pobrania zawiera następujący plik MyXMLFile.xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Powtarzające się elementy, które używają tej samej nazwy elementu, działają, jeśli do rozróżniania elementów jest używany atrybut name:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

Poniższy kod odczytuje poprzedni plik konfiguracji i wyświetla klucze oraz wartości:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

Atrybuty mogą być używane do podawania wartości:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

Poprzedni plik konfiguracji ładuje następujące klucze za pomocą elementu value:

  • key:attribute
  • section:key:attribute

Dostawca konfiguracji typu „klucz na plik”

Element KeyPerFileConfigurationProvider używa plików katalogu jako par klucz-wartość konfiguracji. Klucz to nazwa pliku. Wartość obejmuje zawartość pliku. Dostawca konfiguracji typu „klucz na plik” jest używany w scenariuszach hostingu platformy Docker.

Aby aktywować konfigurację typu „klucz na plik”, wywołaj metodę rozszerzenia AddKeyPerFile w wystąpieniu ConfigurationBuilder. Ścieżka directoryPath do plików musi być ścieżką bezwzględną.

Przeciążenia uniemożliwiają określanie następujących elementów:

  • Delegat Action<KeyPerFileConfigurationSource>, który konfiguruje źródło.
  • Czy katalog jest opcjonalny oraz ścieżka do tego katalogu.

Podwójne podkreślenie (__) jest używane jako ogranicznik klucza konfiguracji w nazwach plików. Na przykład nazwa pliku Logging__LogLevel__System tworzy klucz konfiguracji Logging:LogLevel:System.

Wywołaj ConfigureAppConfiguration podczas kompilowania hosta, aby określić konfigurację aplikacji:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

Dostawca konfiguracji pamięci

Element MemoryConfigurationProvider używa kolekcji w pamięci jako par klucz-wartość konfiguracji.

Poniższy kod dodaje kolekcję pamięci do systemu konfiguracji:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

W poprzednim kodzie element config.AddInMemoryCollection(Dict) jest dodawany po domyślnych dostawcach konfiguracji. Aby uzyskać przykład zamawiania dostawców konfiguracji, zobacz artykuł Dostawca konfiguracji JSON.

Inny przykład korzystający z elementu MemoryConfigurationProvider można znaleźć w sekcji Tworzenie powiązania tablicy.

Konfiguracja punktu końcowego Kestrel

Konfiguracja specyficzna dla punktu końcowego Kestrel zastępuje konfiguracje punktów końcowych między serwerami. Konfiguracje punktów końcowych między serwerami:

Rozważ następujący plik appsettings.json użyty w aplikacji internetowej ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Gdy poprzednia wyróżniona adiustacja jest używana w aplikacji internetowej ASP.NET Core oraz aplikacja jest uruchamiana w wierszu polecenia z użyciem następującej konfiguracji punktu końcowego między serwerami:

dotnet run --urls="https://localhost:7777"

Kestrel wiąże się z punktem końcowym skonfigurowanym specjalnie dla Kestrel w pliku appsettings.json (https://localhost:9999), a nie https://localhost:7777.

Rozważ punkt końcowy specyficzny dla Kestrel, który skonfigurowano jako zmienną środowiskową:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

W poprzedniej zmiennej środowiskowej Https to nazwa punktu końcowego specyficznego dla Kestrel. Poprzedni plik appsettings.json definiuje również punkt końcowy specyficzny dla Kestrel o nazwie Https. Domyślnie zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych są odczytywane po appsettings.{Environment}.json, dlatego poprzednia zmienna środowiskowa jest używana dla punktu końcowego Https.

GetValue

ConfigurationBinder.GetValue wyodrębnia pojedynczą wartość z konfiguracji przy użyciu określonego klucza i konwertuje ją na określony typ:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

Jeśli w poprzednim kodzie element NumberKey nie zostanie znaleziony w konfiguracji, zostanie użyta wartość domyślna 99.

GetSection, GetChildren i Exists

W poniższych przykładach użyj następującego pliku MySubsection.json:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

Następujący kod dodaje element MySubsection.json do dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection zwraca podsekcję konfiguracji z określonym kluczem podsekcji.

Poniższy kod zwraca wartości dla section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

Poniższy kod zwraca wartości dla section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nigdy nie zwraca null. Jeśli nie znaleziono pasującej sekcji, jest zwracany pusty element IConfigurationSection.

Gdy GetSection zwraca pasującą sekcję, element Value nie jest wypełniany. Jeśli sekcja istnieje, zwracane są elementy Key i Path.

GetChildren i Exists

Poniższy kod wywołuje IConfiguration.GetChildren i zwraca wartości dla section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

Poprzedni kod wywołuje ConfigurationExtensions.Exists, aby sprawdzić, czy sekcja istnieje:

Tworzenie tablicy

Element ConfigurationBinder.Bind obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Format tablicy, który uwidacznia numeryczny segment klucza, ma możliwość tworzenia powiązania tablicy z tablicą klas POCO.

Rozważ użycie elementu MyArray.json z przykładowego pliku do pobrania:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

Następujący kod dodaje element MyArray.json do dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

Następujący kod odczytuje konfigurację i wyświetla wartości:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

Poprzedni kod zwraca następujące dane wyjściowe:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

W poprzednich danych wyjściowych indeks 3 ma wartość value40, odpowiadającą wartości "4": "value40", w MyArray.json. Indeksy tablicy powiązanej są ciągłe i nie są powiązane z indeksem kluczy konfiguracji. Integrator nie może powiązać wartości null ani tworzyć wpisów null w powiązanych obiektach.

Niestandardowy dostawca konfiguracji

Przykładowa aplikacja pokazuje, jak utworzyć podstawowego dostawcę konfiguracji, który odczytuje pary klucz-wartość konfiguracji z bazy danych przy użyciu zestawu technologii Entity Framework (EF).

Dostawca ma następujące charakterystyki:

  • Baza danych EF w pamięci jest używana podczas pokazów. Aby używać bazy danych, która wymaga parametrów połączenia, zaimplementuj pomocniczy obiekt ConfigurationBuilder, aby dostarczyć parametry połączenia od innego dostawcy konfiguracji.
  • Dostawca odczytuje tabelę bazy danych do konfiguracji w momencie uruchamiania. Dostawca nie wykonuje zapytań dotyczących bazy danych na podstawie poszczególnych kluczy.
  • Ponowne ładowanie przy zmianie nie jest implementowane, dlatego aktualizacja bazy danych po uruchomieniu aplikacji nie ma wpływu na konfigurację aplikacji.

Zdefiniuj jednostkę EFConfigurationValue służącą do przechowywania wartości konfiguracji w bazie danych.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

Dodaj element EFConfigurationContext służący do przechowywania skonfigurowanych wartości i uzyskiwania do nich dostępu.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

Utwórz klasę, która implementuje IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

Utwórz niestandardowego dostawcę konfiguracji, stosując dziedziczenie z ConfigurationProvider. Dostawca konfiguracji inicjuje bazę danych, gdy jest ona pusta. Ponieważ w kluczach konfiguracji nie jest uwzględniana wielkość liter, słownik używany do inicjowania bazy danych jest tworzony przy użyciu modułu porównywania bez uwzględniania wielkości liter (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Metoda rozszerzenia AddEFConfiguration zezwala na dodawanie źródła konfiguracji do elementu ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

W poniższym kodzie pokazano sposób użycia niestandardowego elementu EFConfigurationProvider w Program.cs:

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

Konfiguracja dostępu za pomocą wstrzykiwania zależności

Konfigurację można wstrzykiwać do usług przy użyciu funkcji wstrzykiwania zależności, rozwiązując usługę IConfiguration:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

Aby uzyskać informacje na temat uzyskiwania dostępu do wartości przy użyciu elementu IConfiguration, zobacz sekcje GetValue oraz GetSection, GetChildren i Exists w tym artykule.

Konfiguracja dostępu w usłudze Razor Pages

Poniższy kod wyświetla dane konfiguracji na stronie usługi Razor Pages:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

W poniższym kodzie element MyOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

Następująca adiustacja używa dyrektywy @injectRazor do rozpoznawania i wyświetlania wartości opcji:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Konfiguracja dostępu w pliku widoku MVC

Poniższy kod wyświetla dane konfiguracji w widoku MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Konfiguracja dostępu w Program.cs

Następujący kod uzyskuje dostęp do konfiguracji w pliku Program.cs.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

W appsettings.json pliku dla poprzedniego przykładu:

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

Konfigurowanie opcji za pomocą delegata

Opcje skonfigurowane w ramach delegata zastępują wartości ustawione w obrębie dostawców konfiguracji.

W poniższym kodzie usługa IConfigureOptions<TOptions> jest dodawana do kontenera usług. Używa ona delegata do konfigurowania wartości dla MyOptions:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

Poniższy kod wyświetla wartości opcji:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

W poprzednim przykładzie wartości parametrów Option1 i Option2 są określane w obszarze appsettings.json, a następnie zastępowane przez skonfigurowanego delegata.

Konfiguracja hosta a konfiguracja aplikacji

Przed skonfigurowaniem i uruchomieniem aplikacji następuje skonfigurowanie i uruchomienie hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Zarówno aplikacja, jak i host są konfigurowane przy użyciu dostawców konfiguracji opisanych w tym temacie. Pary klucz-wartość konfiguracji hosta są również uwzględniane w konfiguracji aplikacji. Aby uzyskać więcej informacji na temat sposobu używania dostawców konfiguracji podczas kompilowania hosta oraz wpływu źródeł konfiguracji na konfigurację hosta, zapoznaj się z omówieniem podstaw platformy ASP.NET Core.

Domyślna konfiguracja hosta

Szczegóły konfiguracji domy.ślnej w przypadku korzystania z hosta internetowego można znaleźć w sekcji dotyczącej platformy ASP.NET Core w wersji 2.2 w tym temacie.

  • Konfiguracja hosta jest dostarczana z:
  • Zostanie ustanowiona domyślna konfiguracja hosta sieci Web (ConfigureWebHostDefaults):
    • Element Kestrel jest używany jako serwer internetowy i konfigurowany przy użyciu dostawców konfiguracji aplikacji.
    • Dodaj oprogramowanie pośredniczące do filtrowania hostów.
    • Dodaj oprogramowanie pośredniczące powiązane z przekazanymi nagłówkami, jeśli zmienna środowiskowa ASPNETCORE_FORWARDEDHEADERS_ENABLED została ustawiona na true.
    • Włącz integrację usług IIS.

Inna konfiguracja

Ten temat dotyczy tylko konfiguracji aplikacji. Inne aspekty uruchamiania i hostowania aplikacji platformy ASP.NET Core są konfigurowane przy użyciu plików konfiguracji, których nie omawiamy w tym temacie:

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym.

Aby uzyskać więcej informacji na temat migrowania konfiguracji aplikacji z wcześniejszych wersji ASP.NET, zobacz Aktualizowanie z ASP.NET do ASP.NET Core.

Dodawanie konfiguracji z zestawu zewnętrznego

Implementacja IHostingStartup umożliwia dodawanie ulepszeń do aplikacji podczas uruchamiania z zestawu zewnętrznego znajdującego się poza klasą Startup aplikacji. Więcej informacji można znaleźć w temacie Korzystanie z hostowania zestawów startowych na platformie ASP.NET Core.

Generator źródła powiązania konfiguracji

Generator źródła powiązania konfiguracji zapewnia konfigurację AOT i trim-friendly. Aby uzyskać więcej informacji, zobacz Generator źródła powiązania konfiguracji.

Dodatkowe zasoby

Konfiguracja aplikacji na platformie ASP.NET Core jest przeprowadzana przy użyciu co najmniej jednego dostawcy konfiguracji. Dostawcy konfiguracji odczytują dane konfiguracji z par klucz-wartość przy użyciu różnych źródeł konfiguracji:

  • Pliki ustawień, takie jak appsettings.json
  • Zmienne środowiskowe
  • Azure Key Vault
  • Azure App Configuration
  • Argumenty wiersza polecenia
  • Dostawcy niestandardowi, zainstalowani lub utworzeni
  • Pliki katalogów
  • Obiekty platformy .NET w pamięci

Ten artykuł zawiera informacje na temat konfiguracji na platformie ASP.NET Core. Aby uzyskać informacje na temat używania konfiguracji w aplikacjach konsoli, zobacz artykuł dotyczący konfiguracji platformy .NET.

Aplikacja i konfiguracja hosta

Aplikacje ASP.NET Core konfigurują i uruchamiają hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Szablony ASP.NET Core umożliwiają tworzenie obiektu WebApplicationBuilder zawierającego host. Chociaż niektóre konfiguracje można wykonać zarówno na hoście, jak i w obrębie dostawców konfiguracji aplikacji, mówiąc ogólnie, tylko konfiguracja niezbędna w przypadku hosta powinna być przeprowadzana w ramach konfiguracji hosta.

Konfiguracja aplikacji ma najwyższy priorytet i została szczegółowo opisana w kolejnej sekcji. Konfiguracja hosta następuje po konfiguracji aplikacji i została opisana w tym artykule.

Domyślne źródła konfiguracji aplikacji

Aplikacje internetowe ASP.NET Core utworzone za pomocą platformy dotnet new lub programu Visual Studio generują następujący kod:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder inicjuje nowe wystąpienie klasy WebApplicationBuilder ze wstępnie skonfigurowanymi wartościami domyślnymi. Zainicjowane narzędzie WebApplicationBuilder (builder) zapewnia domyślną konfigurację aplikacji w następującej kolejności, od priorytetu najwyższego do najniższego:

  1. Argumenty wiersza polecenia, które korzystają z dostawcy konfiguracji wiersza polecenia.
  2. Zmienne środowiskowe bez prefiksu, które korzystają z dostawcy konfiguracji zmiennych środowiskowych bez prefiksu.
  3. Wpisy tajne użytkownika w przypadku aplikacji działającej w środowisku Development.
  4. Element appsettings.{Environment}.json korzystający z dostawcy konfiguracji JSON. Przykład: appsettings.Production.json i appsettings.Development.json.
  5. Plik appsettings.json korzystający z dostawcy konfiguracji JSON.
  6. Alternatywa konfiguracji hosta opisanej w następnej sekcji.

Domyślne źródła konfiguracji hosta

Poniższa lista zawiera domyślne źródła konfiguracji hosta z najwyższego do najniższego priorytetu dla programu WebApplicationBuilder:

  1. Argumenty wiersza polecenia korzystające z dostawcy konfiguracji wiersza polecenia
  2. Zmienne środowiskowe z prefiksem DOTNET_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  3. Zmienne środowiskowe z prefiksem ASPNETCORE_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.

W przypadku hosta ogólnego platformy .NET i hosta sieci Web domyślne źródła konfiguracji hosta z najwyższego do najniższego priorytetu to:

  1. Zmienne środowiskowe z prefiksem ASPNETCORE_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  2. Argumenty wiersza polecenia korzystające z dostawcy konfiguracji wiersza polecenia
  3. Zmienne środowiskowe z prefiksem DOTNET_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.

Jeśli wartość konfiguracji zostanie ustawiona w konfiguracji hosta i aplikacji, będzie używana konfiguracja aplikacji.

Zmienne hosta

Następujące zmienne są blokowane na wczesnym etapie inicjowania konstruktorów hostów i konfiguracja aplikacji nie może mieć na nie wpływu:

Wszystkie pozostałe ustawienia hosta są odczytywane z konfiguracji aplikacji zamiast z konfiguracji hosta.

URLS to jedno z wielu typowych ustawień hosta, które nie jest związane z uruchomieniem. Podobnie jak wszystkie inne ustawienia hosta, których nie ma na liście, ustawienie URLS jest odczytywane później z konfiguracji aplikacji. Konfiguracja hosta to alternatywa konfiguracji aplikacji, więc konfiguracja hosta może służyć do ustawienia elementu URLS, ale zostanie zastąpiona przez dowolne źródło konfiguracji aplikacji, takie jak appsettings.json.

Aby uzyskać więcej informacji, zobacz sekcje Zmienianie katalogu głównego zawartości, nazwy aplikacji i środowiska i Zmienianie katalogu głównego zawartości, nazwy aplikacji i środowiska przy użyciu zmiennych środowiskowych lub wiersza polecenia

Pozostałe sekcje tego artykułu dotyczą konfiguracji aplikacji.

Dostawcy konfiguracji aplikacji

Poniższy kod powoduje wyświetlenie włączonych dostawców konfiguracji w kolejności, w której zostali dodani:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

Poprzednia lista domyślnych źródeł konfiguracji uporządkowanych w kolejności priorytetów od najwyższego do najniższego zawiera dostawców w odwrotnej kolejności, w której są oni dodawani do aplikacji wygenerowanej za pomocą szablonu. Na przykład dostawca konfiguracji JSON jest dodawany przed dostawcą konfiguracji wiersza polecenia.

Dostawcy konfiguracji dodani później mają wyższy priorytet i zastępują poprzednie ustawienia klucza. Jeśli na przykład element MyKey zostanie ustawiony w elemencie appsettings.json i środowisku, będzie używana wartość środowiska. Przy użyciu domyślnych dostawców konfiguracji dostawca konfiguracji wiersza polecenia zastępuje wszystkich innych dostawców.

Aby uzyskać więcej informacji na temat elementu CreateBuilder, zapoznaj się z sekcją Domyślne ustawienia konstruktora.

appsettings.json

Rozważ użycie następującego pliku appsettings.json:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Domyślny element JsonConfigurationProvider powoduje załadowanie konfiguracji w następującej kolejności:

  1. appsettings.json
  2. appsettings.{Environment}.json: na przykład pliki appsettings.Production.json i appsettings.Development.json. Wersja środowiska pliku jest ładowana w oparciu o element IHostingEnvironment.EnvironmentName. Więcej informacji można znaleźć w temacie Używanie wielu środowisk na platformie ASP.NET Core.

Wartości appsettings.{Environment}.json zastępują klucze w pliku appsettings.json. Na przykład domyślnie:

  • W środowisku tworzenia konfiguracja appsettings.Development.json zastępuje wartości znalezione w pliku appsettings.json.
  • W środowisku produkcyjnym konfiguracja appsettings.Production.json zastępuje wartości znalezione w pliku appsettings.json. Na przykład w przypadku wdrażania aplikacji na platformie Azure.

Jeśli wartość konfiguracji musi być gwarantowana, zobacz GetValue. W poprzednim przykładzie odbywa się tylko odczytywanie ciągów, a wartość domyślna nie jest obsługiwana.

W przypadku korzystania z konfiguracji domyślnej włączane są pliki appsettings.json i appsettings.{Environment}.json z elementem reloadOnChange: true. Zmiany wprowadzone w plikach appsettings.json i appsettings.{Environment}.jsonpo uruchomieniu aplikacji są odczytywane przez dostawcę konfiguracji JSON.

Komentarze w appsettings.json

Komentarze w plikach appsettings.json i appsettings.{Environment}.jsonsą obsługiwane przy użyciu komentarzy w stylu języka JavaScript lub C#.

Tworzenie powiązania hierarchicznych danych konfiguracji przy użyciu wzorca opcji

Preferowanym sposobem odczytywania powiązanych wartości konfiguracji jest użycie wzorca opcji. Aby na przykład odczytać następujące wartości konfiguracji:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

Utwórz następującą klasę PositionOptions:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

Klasa opcji:

  • Musi być nieabstrakcyjna z publicznym konstruktorem bez parametrów.
  • Wszystkie publiczne właściwości typu do odczytu i zapisu są powiązane.
  • Pola nie są powiązane. W poprzednim kodzie element Position nie jest powiązany. Dzięki użyciu pola Position ciąg "Position" nie musi być ustalony w aplikacji w przypadku tworzenia powiązania klasy z dostawcą konfiguracji.

Następujący kod powoduje:

  • Wywołanie elementu ConfigurationBinder.Bind w celu powiązania klasy PositionOptions z sekcją Position.
  • Wyświetlenie danych konfiguracji Position.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON są domyślnie odczytywane po uruchomieniu aplikacji.

Element ConfigurationBinder.Get<T> tworzy powiązanie i zwraca określony typ. Element ConfigurationBinder.Get<T> może być wygodniejszy w użyciu niż element ConfigurationBinder.Bind. W poniższym kodzie pokazano sposób użycia elementu ConfigurationBinder.Get<T> z klasą PositionOptions:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON są domyślnie odczytywane po uruchomieniu aplikacji.

Alternatywne podejście w przypadku korzystania z wzorca opcji to utworzenie powiązania sekcji Position i dodanie go do kontenera usługi wstrzykiwania zależności. W poniższym kodzie element PositionOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

Przy użyciu poprzedniego kodu następujący kod odczytuje opcje położenia:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON wprowadzone po uruchomieniu aplikacji nie są odczytywane. Aby odczytać zmiany po uruchomieniu aplikacji, użyj elementu IOptionsSnapshot.

W przypadku korzystania z konfiguracji domyślnej włączane są pliki appsettings.json i appsettings.{Environment}.json z elementem reloadOnChange: true. Zmiany wprowadzone w plikach appsettings.json i appsettings.{Environment}.jsonpo uruchomieniu aplikacji są odczytywane przez dostawcę konfiguracji JSON.

Zobacz opis dostawcy konfiguracji JSON w tym dokumencie, aby uzyskać informacje na temat dodawania kolejnych plików konfiguracji JSON.

Łączenie kolekcji usług

Rozważ użycie następujących elementów, które rejestrują usługi i konfigurują opcje:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

Powiązane grupy rejestracji można przenieść do metody rozszerzenia w celu zarejestrowania usług. Na przykład usługi konfiguracji są dodawane do następującej klasy:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

Pozostałe usługi są rejestrowane w podobnej klasie. Poniższy kod używa nowych metod rozszerzenia do rejestrowania usług:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

Uwaga: każda metoda rozszerzenia services.Add{GROUP_NAME} dodaje i potencjalnie konfiguruje usługi. Na przykład metoda AddControllersWithViews dodaje kontrolery MVC usług z wymaganymi widokami, a metoda AddRazorPages dodaje usługi wymagane przez usługę Razor Pages.

Zabezpieczenia i wpisy tajne użytkownika

Wytyczne dotyczące danych konfiguracji:

  • Nigdy nie przechowuj haseł ani innych poufnych danych w kodzie dostawcy konfiguracji ani w plikach konfiguracji w postaci zwykłego tekstu. Narzędzie Menedżer wpisów tajnych może służyć do przechowywania wpisów tajnych w środowisku tworzenia.
  • Nie używaj wpisów tajnych produkcji w środowiskach tworzenia ani testowania.
  • Określaj wpisy tajne poza projektem, aby nie można było ich przypadkowo zatwierdzić w repozytorium kodu źródłowego.

Domyślnie źródło konfiguracji wpisów tajnych użytkownika jest rejestrowane po źródłach konfiguracji JSON. Dlatego wpisy tajne użytkownika mają pierwszeństwo przed kluczami w plikach appsettings.json i appsettings.{Environment}.json.

Więcej informacji na temat przechowywania haseł i innych danych poufnych:

Azure Key Vault bezpiecznie przechowuje wpisy tajne aplikacji ASP.NET Core. Aby uzyskać więcej informacji, zobacz artykuł Dostawca konfiguracji usługi Azure Key Vault w ASP.NET Core.

Zmienne środowiskowe bez prefiksu

Zmienne środowiskowe bez prefiksów to zmienne środowiskowe inne niż zmienne z prefiksem ASPNETCORE_ lub DOTNET_. Jest to na przykład zestaw szablonów aplikacji internetowych platformy ASP.NET Core "ASPNETCORE_ENVIRONMENT": "Development" w pliku launchSettings.json. Aby uzyskać więcej informacji na temat zmiennych środowiskowych ASPNETCORE_ i DOTNET_, zobacz:

Używając konfiguracji domyślnej, element EnvironmentVariablesConfigurationProvider ładuje konfigurację z par klucz-wartość zmiennej środowiskowej po odczytaniu plików appsettings.json, appsettings.{Environment}.json oraz wpisów tajnych użytkownika. W związku z tym wartości kluczy odczytane ze środowiska zastępują wartości odczytane z plików appsettings.json, appsettings.{Environment}.json oraz wpisów tajnych użytkownika.

Separator : nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Symbol __ (podwójne podkreślenie):

  • Jest obsługiwany przez wszystkie platformy. Na przykład separator : nie jest obsługiwany przez powłokę Bash, a separator __ jest.
  • Jest automatycznie zastępowany przez :

Następujące polecenia set:

set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

Poprzednie ustawienia środowiska:

  • Są ustawiane tylko w procesach uruchamianych z okna poleceń, w których zostały ustawione.
  • Nie będą odczytywane przez przeglądarki uruchamiane przy użyciu programu Visual Studio.

Następujące polecenia setx służą do ustawiania kluczy i wartości środowiska w systemie Windows. W przeciwieństwie do polecenia set, ustawienia polecenia setx są trwałe. Element /M ustawia zmienną w środowisku systemowym. Jeśli przełącznik /M nie jest używany, ustawiana jest zmienna środowiskowa użytkownika.

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

Aby sprawdzić, czy poprzednie polecenia zastępują appsettings.json i appsettings.{Environment}.json:

  • Przy użyciu programu Visual Studio: zamknij i uruchom ponownie program Visual Studio.
  • Za pomocą interfejsu wiersza polecenia: uruchom nowe okno polecenia i wprowadź dotnet run.

Wywołaj polecenie AddEnvironmentVariables z ciągiem, aby określić prefiks zmiennych środowiskowych:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

Powyższy kod:

Prefiks jest usuwany podczas odczytu par klucz-wartość konfiguracji.

Następujące polecenia testują prefiks niestandardowy:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

Konfiguracja domyślna ładuje zmienne środowiskowe i argumenty wiersza polecenia poprzedzone prefiksami DOTNET_ i ASPNETCORE_. Prefiksy DOTNET_ i ASPNETCORE_ są używane na platformie ASP.NET Core na potrzeby konfiguracji hosta i aplikacji, ale nie na potrzeby konfiguracji użytkownika. Aby uzyskać więcej informacji na temat konfiguracji hosta i aplikacji, zobacz artykuł Host ogólny platformy .NET.

W usłudze Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Ustawienia > Konfiguracja. Ustawienia aplikacji usługi Azure App Service są:

  • szyfrowane podczas przechowywania i przesyłane za pośrednictwem zaszyfrowanego kanału,
  • Uwidaczniane jako zmienne środowiskowe.

Aby uzyskać więcej informacji, zobacz Azure Apps: zastępowanie konfiguracji aplikacji przy użyciu witryny Azure Portal.

Zobacz Prefiksy parametrów połączenia, aby uzyskać informacje na temat parametrów połączenia bazy danych platformy Azure.

Nazewnictwo zmiennych środowiskowych

Nazwy zmiennych środowiskowych odzwierciedlają strukturę pliku appsettings.json. Każdy element w hierarchii jest oddzielony podwójnym podkreśleniem (opcja preferowana) lub dwukropkiem. Jeśli struktura elementów zawiera tablicę, indeks tablicy powinien być traktowany jako dodatkowa nazwa elementu w tej ścieżce. Zapoznajmy się z następującym plikiem appsettings.json i jego równoważnymi wartości reprezentowanymi jako zmienne środowiskowe.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

zmienne środowiskowe

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

Zmienne środowiskowe ustawiane w wygenerowanym pliku launchSettings.json

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym. Na przykład szablony internetowe ASP.NET Core generują plik launchSettings.json, który ustawia konfigurację punktu końcowego na:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

Skonfigurowanie applicationUrl ustawia zmienną środowiskową ASPNETCORE_URLS i zastępuje wartości ustawione w środowisku.

Stosowanie opcji ucieczki w zmiennych środowiskowych w systemie Windows

W systemie Linux należy zastosować opcję ucieczki dla zmiennych środowiskowych URL, aby element systemd mógł je przeanalizować. Użyj narzędzia systemd-escape systemu Linux, które daje w wyniku http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

Wyświetlanie zmiennych środowiskowych

Poniższy kod wyświetla wartości i zmienne środowiskowe podczas uruchamiania aplikacji, co może być przydatne podczas debugowania ustawień środowiska:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

Wiersz polecenia

Używając konfiguracji domyślnej, element CommandLineConfigurationProvider ładuje konfigurację z par klucz-wartość argumentów wiersza polecenia po następujących źródłach konfiguracji:

  • Pliki appsettings.json i appsettings.{Environment}.json.
  • Wpisy tajne aplikacji w środowisku deweloperskim.
  • Zmienne środowiskowe.

Domyślnie wartości konfiguracji ustawione w wierszu polecenia zastępują wartości konfiguracji ustawione w ramach wszystkich innych dostawców konfiguracji.

Argumenty wiersza polecenia

Następujące polecenie ustawia klucze i wartości przy użyciu =:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

Następujące polecenie ustawia klucze i wartości przy użyciu /:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

Następujące polecenie ustawia klucze i wartości przy użyciu --:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

Wartość klucza:

  • Musi następować po = lub klucz musi mieć prefiks -- albo /, gdy wartość następuje po spacji.
  • Nie jest wymagana w przypadku użycia elementu =. Na przykład MySetting=.

W tym samym poleceniu nie mieszaj par klucz-wartość argumentu wiersza polecenia, które używają elementu =, z parami klucz-wartość, które używają spacji.

Mapowania przełączników

Mapowania przełączników umożliwiają stosowanie logiki zastępowania nazwy klucza. Udostępnij słownik zamienników przełączników metodzie AddCommandLine.

Jeśli używasz słownika mapowań przełączników, jest on sprawdzany pod kątem klucza zgodnego z kluczem dostarczonym przez argument wiersza polecenia. Po znalezieniu klucza wiersza polecenia w słowniku wartość ze słownika jest przekazywana z powrotem w celu ustawienia pary klucz-wartość w konfiguracji aplikacji. Mapowanie przełącznika jest wymagane dla dowolnego klucza wiersza polecenia poprzedzonego pojedynczym łącznikiem (-).

Reguły dotyczące kluczy słownika mapowania przełączników:

  • Przełączniki muszą zaczynać się od - lub --.
  • Słownik mapowań przełącznika nie może zawierać zduplikowanych kluczy.

Aby używać słownika mapowań przełączników, przekaż go do wywołania do AddCommandLine:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

Uruchom następujące polecenie, aby przetestować zamiennik klucza:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

Poniższy kod pokazuje wartości zastąpionych kluczy:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

W przypadku aplikacji korzystających z mapowań przełączników wywołanie do CreateDefaultBuilder nie powinno przekazywać argumentów. Wywołanie polecenia AddCommandLine w metodzie CreateDefaultBuilder nie uwzględnia mapowanych przełączników i nie ma sposobu na przekazanie słownika mapowań przełączników do CreateDefaultBuilder. Rozwiązaniem nie jest przekazanie argumentów do metody CreateDefaultBuilder, ale zezwolenie umożliwia metodzie AddCommandLine w metodzie ConfigurationBuilder przetwarzanie zarówno argumentów, jak i słownika mapowania przełączników.

Ustawianie argumentów środowiska i wiersza polecenia w programie Visual Studio

Argumenty środowiska i wiersza polecenia można ustawić w programie Visual Studio w oknie dialogowym profilów uruchamiania:

  • W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Właściwości.
  • Wybierz kartę Debugowanie > Ogólne i wybierz pozycję Otwórz interfejs użytkownika debugowania profilów uruchamiania.

Hierarchiczne dane konfiguracji

Interfejs API konfiguracji odczytuje hierarchiczne dane konfiguracji, spłaszczając dane hierarchiczne przy użyciu ogranicznika w kluczach konfiguracji.

Przykładowy materiał do pobrania zawiera następujący plik appsettings.json:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Poniższy kod z przykładowego materiału do pobrania powoduje wyświetlenie kilku ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Preferowanym sposobem odczytywania hierarchicznych danych konfiguracji jest użycie wzorca opcji. Aby uzyskać więcej informacji, zapoznaj się z sekcją Tworzenie powiązania hierarchicznych danych konfiguracji w tym dokumencie.

Metody GetSection i GetChildren są dostępne w przypadki izolowania sesji i elementów podrzędnych sekcji w danych konfiguracji. Te metody zostały dalej opisane w sekcji GetSection, GetChildren i Exists.

Klucze i wartości konfiguracji

Klucze konfiguracji:

  • Nie uwzględniają wielkości liter. Na przykład ConnectionString i connectionstring są traktowane jako klucze równoważne.
  • Jeśli klucz i wartość jest ustawiana w więcej niż jednym dostawcy konfiguracji, zostanie użyta wartość z ostatniego dodanego dostawcy. Aby uzyskać więcej informacji, zobacz Konfiguracja domyślna.
  • Klucze hierarchiczne
    • W interfejsie API konfiguracji separator w postaci dwukropka (:) działa na wszystkich platformach.
    • W zmiennych środowiskowych separator w postaci dwukropka może nie działać na wszystkich platformach. Podwójne podkreślenie (__) jest obsługiwane na wszystkich platformach i jest automatycznie konwertowane na dwukropek (:).
    • W usłudze Azure Key Vault klucze hierarchiczne używają separatora --. Dostawca konfiguracji usługi Azure Key Vault automatycznie zastępuje znak -- znakiem :, gdy wpisy tajne są ładowane do konfiguracji aplikacji.
  • Element ConfigurationBinder obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Tworzenie powiązań tablic jest opisane w sekcji Tworzenie powiązania tablicy z klasą.

Wartości konfiguracji:

  • Są ciągami.
  • Wartości null nie mogą być przechowywane w konfiguracji ani powiązane z obiektami.

Dostawcy konfiguracji

W poniższej tabeli przedstawiono dostawców konfiguracji dostępnych dla aplikacji platformy ASP.NET Core.

Dostawca Dostarcza konfigurację z
Dostawca konfiguracji usługi Azure Key Vault Azure Key Vault
Dostawca konfiguracji aplikacji platformy Azure Azure App Configuration
Dostawca konfiguracji wiersza polecenia Parametry wiersza polecenia
Niestandardowy dostawca konfiguracji Źródło niestandardowe
Dostawca konfiguracji zmiennych środowiskowych Zmienne środowiskowe
Dostawca konfiguracji plików Pliki INI, JSON i XML
Dostawca konfiguracji typu „klucz na plik” Pliki katalogów
Dostawca konfiguracji pamięci Kolekcje w pamięci
Wpisy tajne użytkownika Plik w katalogu profilów użytkownika

Źródła konfiguracji są odczytywane w kolejności, w której określono odpowiednich dostawców konfiguracji. Uporządkuj dostawców konfiguracji w kodzie, aby dopasować priorytety do bazowych źródeł konfiguracji, których wymaga aplikacja.

Typowa sekwencja dostawców konfiguracji to:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. Wpisy tajne użytkownika
  4. Zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  5. Argumenty wiersza polecenia, które korzystają z dostawcy konfiguracji wiersza polecenia.

Powszechną praktyką jest dodawanie dostawcy konfiguracji wiersza polecenia jako ostatniego w serii dostawców, aby zezwolić argumentom wiersza polecenia na zastępowanie konfiguracji ustawionych przez innych dostawców.

Poprzednia sekwencja dostawców jest używana w konfiguracji domyślnej.

Prefiksy parametrów połączenia

Interfejs API konfiguracji ma specjalne reguły przetwarzania dla czterech zmiennych środowiskowych parametrów połączenia. Te parametry połączenia są uwzględniane podczas konfigurowania parametrów połączenia platformy Azure dla środowiska aplikacji. Zmienne środowiskowe z prefiksami pokazanymi w tabeli są ładowane do aplikacji z użyciem konfiguracji domyślnej lub gdy prefiks nie zostanie dostarczony do elementu AddEnvironmentVariables.

Prefiks parametrów połączenia Dostawca
CUSTOMCONNSTR_ Dostawca niestandardowy
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

Gdy zmienna środowiskowa zostanie odnaleziona i załadowana do konfiguracji z dowolnym z czterech prefiksów pokazanych w tabeli:

  • Klucz konfiguracji jest tworzony przez usunięcie prefiksu zmiennej środowiskowej i dodanie sekcji klucza konfiguracji (ConnectionStrings).
  • Tworzona jest nowa para klucz-wartość konfiguracji, która reprezentuje dostawcę połączenia z bazą danych (z wyjątkiem elementu CUSTOMCONNSTR_, który nie ma podanego dostawcy).
Klucz zmiennej środowiskowej Przekonwertowany klucz konfiguracji Wpis konfiguracji dostawcy
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Wpis konfiguracji nie został utworzony.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: System.Data.SqlClient

Dostawca konfiguracji plików

FileConfigurationProvider to klasa bazowa na potrzeby ładowania konfiguracji z systemu plików. Następujący dostawcy konfiguracji pochodzą z obiektu FileConfigurationProvider:

Dostawca konfiguracji plików INI

Element IniConfigurationProvider ładuje konfigurację z par klucz-wartość pliku INI w czasie wykonywania.

Poniższy kod dodaje kilku dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

W poprzednim kodzie ustawienia w plikach MyIniConfig.ini i MyIniConfig.{Environment}.ini są zastępowane przez ustawienia w następujących obszarach:

Przykładowy materiał do pobrania zawiera następujący plik MyIniConfig.ini:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Dostawca konfiguracji plików JSON

Element JsonConfigurationProvider ładuje konfigurację z par klucz-wartość pliku JSON.

Przeciążenia mogą wskazywać, czy:

  • Plik jest opcjonalny.
  • Konfiguracja zostanie ponownie załadowana, jeśli plik się zmieni.

Spójrzmy na poniższy kod:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

Powyższy kod ma następujące działanie:

Zazwyczaj nie chcesz, aby niestandardowy plik JSON zastępował wartości ustawione w obrębie dostawcy konfiguracji zmiennych środowiskowych i dostawcy konfiguracji wiersza polecenia.

Dostawca konfiguracji plików XML

Element XmlConfigurationProvider ładuje konfigurację z par klucz-wartość pliku XML w czasie wykonywania.

Poniższy kod dodaje kilku dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

W poprzednim kodzie ustawienia w plikach MyXMLFile.xml i MyXMLFile.{Environment}.xml są zastępowane przez ustawienia w następujących obszarach:

Przykładowy materiał do pobrania zawiera następujący plik MyXMLFile.xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Powtarzające się elementy, które używają tej samej nazwy elementu, działają, jeśli do rozróżniania elementów jest używany atrybut name:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

Poniższy kod odczytuje poprzedni plik konfiguracji i wyświetla klucze oraz wartości:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

Atrybuty mogą być używane do podawania wartości:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

Poprzedni plik konfiguracji ładuje następujące klucze za pomocą elementu value:

  • key:attribute
  • section:key:attribute

Dostawca konfiguracji typu „klucz na plik”

Element KeyPerFileConfigurationProvider używa plików katalogu jako par klucz-wartość konfiguracji. Klucz to nazwa pliku. Wartość obejmuje zawartość pliku. Dostawca konfiguracji typu „klucz na plik” jest używany w scenariuszach hostingu platformy Docker.

Aby aktywować konfigurację typu „klucz na plik”, wywołaj metodę rozszerzenia AddKeyPerFile w wystąpieniu ConfigurationBuilder. Ścieżka directoryPath do plików musi być ścieżką bezwzględną.

Przeciążenia uniemożliwiają określanie następujących elementów:

  • Delegat Action<KeyPerFileConfigurationSource>, który konfiguruje źródło.
  • Czy katalog jest opcjonalny oraz ścieżka do tego katalogu.

Podwójne podkreślenie (__) jest używane jako ogranicznik klucza konfiguracji w nazwach plików. Na przykład nazwa pliku Logging__LogLevel__System tworzy klucz konfiguracji Logging:LogLevel:System.

Wywołaj ConfigureAppConfiguration podczas kompilowania hosta, aby określić konfigurację aplikacji:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

Dostawca konfiguracji pamięci

Element MemoryConfigurationProvider używa kolekcji w pamięci jako par klucz-wartość konfiguracji.

Poniższy kod dodaje kolekcję pamięci do systemu konfiguracji:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

W poprzednim kodzie element config.AddInMemoryCollection(Dict) jest dodawany po domyślnych dostawcach konfiguracji. Aby uzyskać przykład zamawiania dostawców konfiguracji, zobacz artykuł Dostawca konfiguracji JSON.

Inny przykład korzystający z elementu MemoryConfigurationProvider można znaleźć w sekcji Tworzenie powiązania tablicy.

Konfiguracja punktu końcowego Kestrel

Konfiguracja specyficzna dla punktu końcowego Kestrel zastępuje konfiguracje punktów końcowych między serwerami. Konfiguracje punktów końcowych między serwerami:

Rozważ następujący plik appsettings.json użyty w aplikacji internetowej ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Gdy poprzednia wyróżniona adiustacja jest używana w aplikacji internetowej ASP.NET Core oraz aplikacja jest uruchamiana w wierszu polecenia z użyciem następującej konfiguracji punktu końcowego między serwerami:

dotnet run --urls="https://localhost:7777"

Kestrel wiąże się z punktem końcowym skonfigurowanym specjalnie dla Kestrel w pliku appsettings.json (https://localhost:9999), a nie https://localhost:7777.

Rozważ punkt końcowy specyficzny dla Kestrel, który skonfigurowano jako zmienną środowiskową:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

W poprzedniej zmiennej środowiskowej Https to nazwa punktu końcowego specyficznego dla Kestrel. Poprzedni plik appsettings.json definiuje również punkt końcowy specyficzny dla Kestrel o nazwie Https. Domyślnie zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych są odczytywane po appsettings.{Environment}.json, dlatego poprzednia zmienna środowiskowa jest używana dla punktu końcowego Https.

GetValue

ConfigurationBinder.GetValue wyodrębnia pojedynczą wartość z konfiguracji przy użyciu określonego klucza i konwertuje ją na określony typ:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

Jeśli w poprzednim kodzie element NumberKey nie zostanie znaleziony w konfiguracji, zostanie użyta wartość domyślna 99.

GetSection, GetChildren i Exists

W poniższych przykładach użyj następującego pliku MySubsection.json:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

Następujący kod dodaje element MySubsection.json do dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection zwraca podsekcję konfiguracji z określonym kluczem podsekcji.

Poniższy kod zwraca wartości dla section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

Poniższy kod zwraca wartości dla section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nigdy nie zwraca null. Jeśli nie znaleziono pasującej sekcji, jest zwracany pusty element IConfigurationSection.

Gdy GetSection zwraca pasującą sekcję, element Value nie jest wypełniany. Jeśli sekcja istnieje, zwracane są elementy Key i Path.

GetChildren i Exists

Poniższy kod wywołuje IConfiguration.GetChildren i zwraca wartości dla section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

Poprzedni kod wywołuje ConfigurationExtensions.Exists, aby sprawdzić, czy sekcja istnieje:

Tworzenie tablicy

Element ConfigurationBinder.Bind obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Format tablicy, który uwidacznia numeryczny segment klucza, ma możliwość tworzenia powiązania tablicy z tablicą klas POCO.

Rozważ użycie elementu MyArray.json z przykładowego pliku do pobrania:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

Następujący kod dodaje element MyArray.json do dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

Następujący kod odczytuje konfigurację i wyświetla wartości:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

Poprzedni kod zwraca następujące dane wyjściowe:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

W poprzednich danych wyjściowych indeks 3 ma wartość value40, odpowiadającą wartości "4": "value40", w MyArray.json. Indeksy tablicy powiązanej są ciągłe i nie są powiązane z indeksem kluczy konfiguracji. Integrator nie może powiązać wartości null ani tworzyć wpisów null w powiązanych obiektach.

Niestandardowy dostawca konfiguracji

Przykładowa aplikacja pokazuje, jak utworzyć podstawowego dostawcę konfiguracji, który odczytuje pary klucz-wartość konfiguracji z bazy danych przy użyciu zestawu technologii Entity Framework (EF).

Dostawca ma następujące charakterystyki:

  • Baza danych EF w pamięci jest używana podczas pokazów. Aby używać bazy danych, która wymaga parametrów połączenia, zaimplementuj pomocniczy obiekt ConfigurationBuilder, aby dostarczyć parametry połączenia od innego dostawcy konfiguracji.
  • Dostawca odczytuje tabelę bazy danych do konfiguracji w momencie uruchamiania. Dostawca nie wykonuje zapytań dotyczących bazy danych na podstawie poszczególnych kluczy.
  • Ponowne ładowanie przy zmianie nie jest implementowane, dlatego aktualizacja bazy danych po uruchomieniu aplikacji nie ma wpływu na konfigurację aplikacji.

Zdefiniuj jednostkę EFConfigurationValue służącą do przechowywania wartości konfiguracji w bazie danych.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

Dodaj element EFConfigurationContext służący do przechowywania skonfigurowanych wartości i uzyskiwania do nich dostępu.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

Utwórz klasę, która implementuje IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

Utwórz niestandardowego dostawcę konfiguracji, stosując dziedziczenie z ConfigurationProvider. Dostawca konfiguracji inicjuje bazę danych, gdy jest ona pusta. Ponieważ w kluczach konfiguracji nie jest uwzględniana wielkość liter, słownik używany do inicjowania bazy danych jest tworzony przy użyciu modułu porównywania bez uwzględniania wielkości liter (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Metoda rozszerzenia AddEFConfiguration zezwala na dodawanie źródła konfiguracji do elementu ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

W poniższym kodzie pokazano sposób użycia niestandardowego elementu EFConfigurationProvider w Program.cs:

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

Konfiguracja dostępu za pomocą wstrzykiwania zależności

Konfigurację można wstrzykiwać do usług przy użyciu funkcji wstrzykiwania zależności, rozwiązując usługę IConfiguration:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

Aby uzyskać informacje na temat uzyskiwania dostępu do wartości przy użyciu elementu IConfiguration, zobacz sekcje GetValue oraz GetSection, GetChildren i Exists w tym artykule.

Konfiguracja dostępu w usłudze Razor Pages

Poniższy kod wyświetla dane konfiguracji na stronie usługi Razor Pages:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

W poniższym kodzie element MyOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

Następująca adiustacja używa dyrektywy @injectRazor do rozpoznawania i wyświetlania wartości opcji:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Konfiguracja dostępu w pliku widoku MVC

Poniższy kod wyświetla dane konfiguracji w widoku MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Konfiguracja dostępu w Program.cs

Następujący kod uzyskuje dostęp do konfiguracji w pliku Program.cs.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

W appsettings.json pliku dla poprzedniego przykładu:

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

Konfigurowanie opcji za pomocą delegata

Opcje skonfigurowane w ramach delegata zastępują wartości ustawione w obrębie dostawców konfiguracji.

W poniższym kodzie usługa IConfigureOptions<TOptions> jest dodawana do kontenera usług. Używa ona delegata do konfigurowania wartości dla MyOptions:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

Poniższy kod wyświetla wartości opcji:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

W poprzednim przykładzie wartości parametrów Option1 i Option2 są określane w obszarze appsettings.json, a następnie zastępowane przez skonfigurowanego delegata.

Konfiguracja hosta a konfiguracja aplikacji

Przed skonfigurowaniem i uruchomieniem aplikacji następuje skonfigurowanie i uruchomienie hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Zarówno aplikacja, jak i host są konfigurowane przy użyciu dostawców konfiguracji opisanych w tym temacie. Pary klucz-wartość konfiguracji hosta są również uwzględniane w konfiguracji aplikacji. Aby uzyskać więcej informacji na temat sposobu używania dostawców konfiguracji podczas kompilowania hosta oraz wpływu źródeł konfiguracji na konfigurację hosta, zapoznaj się z omówieniem podstaw platformy ASP.NET Core.

Domyślna konfiguracja hosta

Szczegóły konfiguracji domy.ślnej w przypadku korzystania z hosta internetowego można znaleźć w sekcji dotyczącej platformy ASP.NET Core w wersji 2.2 w tym temacie.

  • Konfiguracja hosta jest dostarczana z:
  • Zostanie ustanowiona domyślna konfiguracja hosta sieci Web (ConfigureWebHostDefaults):
    • Element Kestrel jest używany jako serwer internetowy i konfigurowany przy użyciu dostawców konfiguracji aplikacji.
    • Dodaj oprogramowanie pośredniczące do filtrowania hostów.
    • Dodaj oprogramowanie pośredniczące powiązane z przekazanymi nagłówkami, jeśli zmienna środowiskowa ASPNETCORE_FORWARDEDHEADERS_ENABLED została ustawiona na true.
    • Włącz integrację usług IIS.

Inna konfiguracja

Ten temat dotyczy tylko konfiguracji aplikacji. Inne aspekty uruchamiania i hostowania aplikacji platformy ASP.NET Core są konfigurowane przy użyciu plików konfiguracji, których nie omawiamy w tym temacie:

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym.

Aby uzyskać więcej informacji na temat migrowania konfiguracji aplikacji z wcześniejszych wersji ASP.NET, zobacz Aktualizowanie z ASP.NET do ASP.NET Core.

Dodawanie konfiguracji z zestawu zewnętrznego

Implementacja IHostingStartup umożliwia dodawanie ulepszeń do aplikacji podczas uruchamiania z zestawu zewnętrznego znajdującego się poza klasą Startup aplikacji. Więcej informacji można znaleźć w temacie Korzystanie z hostowania zestawów startowych na platformie ASP.NET Core.

Dodatkowe zasoby

Konfiguracja aplikacji na platformie ASP.NET Core jest przeprowadzana przy użyciu co najmniej jednego dostawcy konfiguracji. Dostawcy konfiguracji odczytują dane konfiguracji z par klucz-wartość przy użyciu różnych źródeł konfiguracji:

  • Pliki ustawień, takie jak appsettings.json
  • Zmienne środowiskowe
  • Azure Key Vault
  • Azure App Configuration
  • Argumenty wiersza polecenia
  • Dostawcy niestandardowi, zainstalowani lub utworzeni
  • Pliki katalogów
  • Obiekty platformy .NET w pamięci

Ten artykuł zawiera informacje na temat konfiguracji na platformie ASP.NET Core. Aby uzyskać informacje na temat używania konfiguracji w aplikacjach konsoli, zobacz artykuł dotyczący konfiguracji platformy .NET.

Aplikacja i konfiguracja hosta

Aplikacje ASP.NET Core konfigurują i uruchamiają hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Szablony ASP.NET Core umożliwiają tworzenie obiektu WebApplicationBuilder zawierającego host. Chociaż niektóre konfiguracje można wykonać zarówno na hoście, jak i w obrębie dostawców konfiguracji aplikacji, mówiąc ogólnie, tylko konfiguracja niezbędna w przypadku hosta powinna być przeprowadzana w ramach konfiguracji hosta.

Konfiguracja aplikacji ma najwyższy priorytet i została szczegółowo opisana w kolejnej sekcji. Konfiguracja hosta następuje po konfiguracji aplikacji i została opisana w tym artykule.

Domyślne źródła konfiguracji aplikacji

Aplikacje internetowe ASP.NET Core utworzone za pomocą platformy dotnet new lub programu Visual Studio generują następujący kod:

var builder = WebApplication.CreateBuilder(args);

WebApplication.CreateBuilder inicjuje nowe wystąpienie klasy WebApplicationBuilder ze wstępnie skonfigurowanymi wartościami domyślnymi. Zainicjowane narzędzie WebApplicationBuilder (builder) zapewnia domyślną konfigurację aplikacji w następującej kolejności, od priorytetu najwyższego do najniższego:

  1. Argumenty wiersza polecenia, które korzystają z dostawcy konfiguracji wiersza polecenia.
  2. Zmienne środowiskowe bez prefiksu, które korzystają z dostawcy konfiguracji zmiennych środowiskowych bez prefiksu.
  3. Wpisy tajne użytkownika w przypadku aplikacji działającej w środowisku Development.
  4. Element appsettings.{Environment}.json korzystający z dostawcy konfiguracji JSON. Przykład: appsettings.Production.json i appsettings.Development.json.
  5. Plik appsettings.json korzystający z dostawcy konfiguracji JSON.
  6. Alternatywa konfiguracji hosta opisanej w następnej sekcji.

Domyślne źródła konfiguracji hosta

Poniższa lista zawiera domyślne źródła konfiguracji hosta w kolejności od priorytetu najwyższego do najniższego:

  1. Zmienne środowiskowe z prefiksem ASPNETCORE_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  2. Argumenty wiersza polecenia korzystające z dostawcy konfiguracji wiersza polecenia
  3. Zmienne środowiskowe z prefiksem DOTNET_ korzystające z dostawcy konfiguracji zmiennych środowiskowych.

Jeśli wartość konfiguracji zostanie ustawiona w konfiguracji hosta i aplikacji, będzie używana konfiguracja aplikacji.

Zobacz sekcję Explanation (Wyjaśnienie) w tym komentarzu dotyczącym usługi GitHub, aby dowiedzieć się, dlaczego w konfiguracji hosta zmienne środowiskowe z prefiksem ASPNETCORE_ mają wyższy priorytet niż argumenty wiersza polecenia.

Zmienne hosta

Następujące zmienne są blokowane na wczesnym etapie inicjowania konstruktorów hostów i konfiguracja aplikacji nie może mieć na nie wpływu:

Wszystkie pozostałe ustawienia hosta są odczytywane z konfiguracji aplikacji zamiast z konfiguracji hosta.

URLS to jedno z wielu typowych ustawień hosta, które nie jest związane z uruchomieniem. Podobnie jak wszystkie inne ustawienia hosta, których nie ma na liście, ustawienie URLS jest odczytywane później z konfiguracji aplikacji. Konfiguracja hosta to alternatywa konfiguracji aplikacji, więc konfiguracja hosta może służyć do ustawienia elementu URLS, ale zostanie zastąpiona przez dowolne źródło konfiguracji aplikacji, takie jak appsettings.json.

Aby uzyskać więcej informacji, zobacz sekcje Zmienianie katalogu głównego zawartości, nazwy aplikacji i środowiska i Zmienianie katalogu głównego zawartości, nazwy aplikacji i środowiska przy użyciu zmiennych środowiskowych lub wiersza polecenia

Pozostałe sekcje tego artykułu dotyczą konfiguracji aplikacji.

Dostawcy konfiguracji aplikacji

Poniższy kod powoduje wyświetlenie włączonych dostawców konfiguracji w kolejności, w której zostali dodani:

public class Index2Model : PageModel
{
    private IConfigurationRoot ConfigRoot;

    public Index2Model(IConfiguration configRoot)
    {
        ConfigRoot = (IConfigurationRoot)configRoot;
    }

    public ContentResult OnGet()
    {           
        string str = "";
        foreach (var provider in ConfigRoot.Providers.ToList())
        {
            str += provider.ToString() + "\n";
        }

        return Content(str);
    }
}

Poprzednia lista domyślnych źródeł konfiguracji uporządkowanych w kolejności priorytetów od najwyższego do najniższego zawiera dostawców w odwrotnej kolejności, w której są oni dodawani do aplikacji wygenerowanej za pomocą szablonu. Na przykład dostawca konfiguracji JSON jest dodawany przed dostawcą konfiguracji wiersza polecenia.

Dostawcy konfiguracji dodani później mają wyższy priorytet i zastępują poprzednie ustawienia klucza. Jeśli na przykład element MyKey zostanie ustawiony w elemencie appsettings.json i środowisku, będzie używana wartość środowiska. Przy użyciu domyślnych dostawców konfiguracji dostawca konfiguracji wiersza polecenia zastępuje wszystkich innych dostawców.

Aby uzyskać więcej informacji na temat elementu CreateBuilder, zapoznaj się z sekcją Domyślne ustawienia konstruktora.

appsettings.json

Rozważ użycie następującego pliku appsettings.json:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Domyślny element JsonConfigurationProvider powoduje załadowanie konfiguracji w następującej kolejności:

  1. appsettings.json
  2. appsettings.{Environment}.json: na przykład pliki appsettings.Production.json i appsettings.Development.json. Wersja środowiska pliku jest ładowana w oparciu o element IHostingEnvironment.EnvironmentName. Więcej informacji można znaleźć w temacie Używanie wielu środowisk na platformie ASP.NET Core.

Wartości appsettings.{Environment}.json zastępują klucze w pliku appsettings.json. Na przykład domyślnie:

  • W środowisku tworzenia konfiguracja appsettings.Development.json zastępuje wartości znalezione w pliku appsettings.json.
  • W środowisku produkcyjnym konfiguracja appsettings.Production.json zastępuje wartości znalezione w pliku appsettings.json. Na przykład w przypadku wdrażania aplikacji na platformie Azure.

Jeśli wartość konfiguracji musi być gwarantowana, zobacz GetValue. W poprzednim przykładzie odbywa się tylko odczytywanie ciągów, a wartość domyślna nie jest obsługiwana.

W przypadku korzystania z konfiguracji domyślnej włączane są pliki appsettings.json i appsettings.{Environment}.json z elementem reloadOnChange: true. Zmiany wprowadzone w plikach appsettings.json i appsettings.{Environment}.jsonpo uruchomieniu aplikacji są odczytywane przez dostawcę konfiguracji JSON.

Tworzenie powiązania hierarchicznych danych konfiguracji przy użyciu wzorca opcji

Preferowanym sposobem odczytywania powiązanych wartości konfiguracji jest użycie wzorca opcji. Aby na przykład odczytać następujące wartości konfiguracji:

  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  }

Utwórz następującą klasę PositionOptions:

public class PositionOptions
{
    public const string Position = "Position";

    public string Title { get; set; } = String.Empty;
    public string Name { get; set; } = String.Empty;
}

Klasa opcji:

  • Musi być nieabstrakcyjna z publicznym konstruktorem bez parametrów.
  • Wszystkie publiczne właściwości typu do odczytu i zapisu są powiązane.
  • Pola nie są powiązane. W poprzednim kodzie element Position nie jest powiązany. Dzięki użyciu pola Position ciąg "Position" nie musi być ustalony w aplikacji w przypadku tworzenia powiązania klasy z dostawcą konfiguracji.

Następujący kod powoduje:

  • Wywołanie elementu ConfigurationBinder.Bind w celu powiązania klasy PositionOptions z sekcją Position.
  • Wyświetlenie danych konfiguracji Position.
public class Test22Model : PageModel
{
    private readonly IConfiguration Configuration;

    public Test22Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var positionOptions = new PositionOptions();
        Configuration.GetSection(PositionOptions.Position).Bind(positionOptions);

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON są domyślnie odczytywane po uruchomieniu aplikacji.

Element ConfigurationBinder.Get<T> tworzy powiązanie i zwraca określony typ. Element ConfigurationBinder.Get<T> może być wygodniejszy w użyciu niż element ConfigurationBinder.Bind. W poniższym kodzie pokazano sposób użycia elementu ConfigurationBinder.Get<T> z klasą PositionOptions:

public class Test21Model : PageModel
{
    private readonly IConfiguration Configuration;
    public PositionOptions? positionOptions { get; private set; }

    public Test21Model(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {            
        positionOptions = Configuration.GetSection(PositionOptions.Position)
                                                     .Get<PositionOptions>();

        return Content($"Title: {positionOptions.Title} \n" +
                       $"Name: {positionOptions.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON są domyślnie odczytywane po uruchomieniu aplikacji.

Alternatywne podejście w przypadku korzystania z wzorca opcji to utworzenie powiązania sekcji Position i dodanie go do kontenera usługi wstrzykiwania zależności. W poniższym kodzie element PositionOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));

var app = builder.Build();

Przy użyciu poprzedniego kodu następujący kod odczytuje opcje położenia:

public class Test2Model : PageModel
{
    private readonly PositionOptions _options;

    public Test2Model(IOptions<PositionOptions> options)
    {
        _options = options.Value;
    }

    public ContentResult OnGet()
    {
        return Content($"Title: {_options.Title} \n" +
                       $"Name: {_options.Name}");
    }
}

W poprzednim kodzie zmiany pliku konfiguracji JSON wprowadzone po uruchomieniu aplikacji nie są odczytywane. Aby odczytać zmiany po uruchomieniu aplikacji, użyj elementu IOptionsSnapshot.

W przypadku korzystania z konfiguracji domyślnej włączane są pliki appsettings.json i appsettings.{Environment}.json z elementem reloadOnChange: true. Zmiany wprowadzone w plikach appsettings.json i appsettings.{Environment}.jsonpo uruchomieniu aplikacji są odczytywane przez dostawcę konfiguracji JSON.

Zobacz opis dostawcy konfiguracji JSON w tym dokumencie, aby uzyskać informacje na temat dodawania kolejnych plików konfiguracji JSON.

Łączenie kolekcji usług

Rozważ użycie następujących elementów, które rejestrują usługi i konfigurują opcje:

using ConfigSample.Options;
using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<PositionOptions>(
    builder.Configuration.GetSection(PositionOptions.Position));
builder.Services.Configure<ColorOptions>(
    builder.Configuration.GetSection(ColorOptions.Color));

builder.Services.AddScoped<IMyDependency, MyDependency>();
builder.Services.AddScoped<IMyDependency2, MyDependency2>();

var app = builder.Build();

Powiązane grupy rejestracji można przenieść do metody rozszerzenia w celu zarejestrowania usług. Na przykład usługi konfiguracji są dodawane do następującej klasy:

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services;
        }

        public static IServiceCollection AddMyDependencyGroup(
             this IServiceCollection services)
        {
            services.AddScoped<IMyDependency, MyDependency>();
            services.AddScoped<IMyDependency2, MyDependency2>();

            return services;
        }
    }
}

Pozostałe usługi są rejestrowane w podobnej klasie. Poniższy kod używa nowych metod rozszerzenia do rejestrowania usług:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddConfig(builder.Configuration)
    .AddMyDependencyGroup();

builder.Services.AddRazorPages();

var app = builder.Build();

Uwaga: każda metoda rozszerzenia services.Add{GROUP_NAME} dodaje i potencjalnie konfiguruje usługi. Na przykład metoda AddControllersWithViews dodaje kontrolery MVC usług z wymaganymi widokami, a metoda AddRazorPages dodaje usługi wymagane przez usługę Razor Pages.

Zabezpieczenia i wpisy tajne użytkownika

Wytyczne dotyczące danych konfiguracji:

  • Nigdy nie przechowuj haseł ani innych poufnych danych w kodzie dostawcy konfiguracji ani w plikach konfiguracji w postaci zwykłego tekstu. Narzędzie Menedżer wpisów tajnych może służyć do przechowywania wpisów tajnych w środowisku tworzenia.
  • Nie używaj wpisów tajnych produkcji w środowiskach tworzenia ani testowania.
  • Określaj wpisy tajne poza projektem, aby nie można było ich przypadkowo zatwierdzić w repozytorium kodu źródłowego.

Domyślnie źródło konfiguracji wpisów tajnych użytkownika jest rejestrowane po źródłach konfiguracji JSON. Dlatego wpisy tajne użytkownika mają pierwszeństwo przed kluczami w plikach appsettings.json i appsettings.{Environment}.json.

Więcej informacji na temat przechowywania haseł i innych danych poufnych:

Azure Key Vault bezpiecznie przechowuje wpisy tajne aplikacji ASP.NET Core. Aby uzyskać więcej informacji, zobacz artykuł Dostawca konfiguracji usługi Azure Key Vault w ASP.NET Core.

Zmienne środowiskowe bez prefiksu

Zmienne środowiskowe bez prefiksów to zmienne środowiskowe inne niż zmienne z prefiksem ASPNETCORE_ lub DOTNET_. Jest to na przykład zestaw szablonów aplikacji internetowych platformy ASP.NET Core "ASPNETCORE_ENVIRONMENT": "Development" w pliku launchSettings.json. Aby uzyskać więcej informacji na temat zmiennych środowiskowych ASPNETCORE_ i DOTNET_, zobacz:

Używając konfiguracji domyślnej, element EnvironmentVariablesConfigurationProvider ładuje konfigurację z par klucz-wartość zmiennej środowiskowej po odczytaniu plików appsettings.json, appsettings.{Environment}.json oraz wpisów tajnych użytkownika. W związku z tym wartości kluczy odczytane ze środowiska zastępują wartości odczytane z plików appsettings.json, appsettings.{Environment}.json oraz wpisów tajnych użytkownika.

Separator : nie współdziała z kluczami hierarchicznymi zmiennych środowiskowych na wszystkich platformach. Symbol __ (podwójne podkreślenie):

  • Jest obsługiwany przez wszystkie platformy. Na przykład separator : nie jest obsługiwany przez powłokę Bash, a separator __ jest.
  • Jest automatycznie zastępowany przez :

Następujące polecenia set:

set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

Poprzednie ustawienia środowiska:

  • Są ustawiane tylko w procesach uruchamianych z okna poleceń, w których zostały ustawione.
  • Nie będą odczytywane przez przeglądarki uruchamiane przy użyciu programu Visual Studio.

Następujące polecenia setx służą do ustawiania kluczy i wartości środowiska w systemie Windows. W przeciwieństwie do polecenia set, ustawienia polecenia setx są trwałe. Element /M ustawia zmienną w środowisku systemowym. Jeśli przełącznik /M nie jest używany, ustawiana jest zmienna środowiskowa użytkownika.

setx MyKey "My key from setx Environment" /M
setx Position__Title Environment_Editor /M
setx Position__Name Environment_Rick /M

Aby sprawdzić, czy poprzednie polecenia zastępują appsettings.json i appsettings.{Environment}.json:

  • Przy użyciu programu Visual Studio: zamknij i uruchom ponownie program Visual Studio.
  • Za pomocą interfejsu wiersza polecenia: uruchom nowe okno polecenia i wprowadź dotnet run.

Wywołaj polecenie AddEnvironmentVariables z ciągiem, aby określić prefiks zmiennych środowiskowych:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Configuration.AddEnvironmentVariables(prefix: "MyCustomPrefix_");

var app = builder.Build();

Powyższy kod:

Prefiks jest usuwany podczas odczytu par klucz-wartość konfiguracji.

Następujące polecenia testują prefiks niestandardowy:

set MyCustomPrefix_MyKey="My key with MyCustomPrefix_ Environment"
set MyCustomPrefix_Position__Title=Editor_with_customPrefix
set MyCustomPrefix_Position__Name=Environment_Rick_cp
dotnet run

Konfiguracja domyślna ładuje zmienne środowiskowe i argumenty wiersza polecenia poprzedzone prefiksami DOTNET_ i ASPNETCORE_. Prefiksy DOTNET_ i ASPNETCORE_ są używane na platformie ASP.NET Core na potrzeby konfiguracji hosta i aplikacji, ale nie na potrzeby konfiguracji użytkownika. Aby uzyskać więcej informacji na temat konfiguracji hosta i aplikacji, zobacz artykuł Host ogólny platformy .NET.

W usłudze Azure App Service wybierz pozycję Nowe ustawienie aplikacji na stronie Ustawienia > Konfiguracja. Ustawienia aplikacji usługi Azure App Service są:

  • szyfrowane podczas przechowywania i przesyłane za pośrednictwem zaszyfrowanego kanału,
  • Uwidaczniane jako zmienne środowiskowe.

Aby uzyskać więcej informacji, zobacz Azure Apps: zastępowanie konfiguracji aplikacji przy użyciu witryny Azure Portal.

Zobacz Prefiksy parametrów połączenia, aby uzyskać informacje na temat parametrów połączenia bazy danych platformy Azure.

Nazewnictwo zmiennych środowiskowych

Nazwy zmiennych środowiskowych odzwierciedlają strukturę pliku appsettings.json. Każdy element w hierarchii jest oddzielony podwójnym podkreśleniem (opcja preferowana) lub dwukropkiem. Jeśli struktura elementów zawiera tablicę, indeks tablicy powinien być traktowany jako dodatkowa nazwa elementu w tej ścieżce. Zapoznajmy się z następującym plikiem appsettings.json i jego równoważnymi wartości reprezentowanymi jako zmienne środowiskowe.

appsettings.json

{
    "SmtpServer": "smtp.example.com",
    "Logging": [
        {
            "Name": "ToEmail",
            "Level": "Critical",
            "Args": {
                "FromAddress": "MySystem@example.com",
                "ToAddress": "SRE@example.com"
            }
        },
        {
            "Name": "ToConsole",
            "Level": "Information"
        }
    ]
}

zmienne środowiskowe

setx SmtpServer smtp.example.com
setx Logging__0__Name ToEmail
setx Logging__0__Level Critical
setx Logging__0__Args__FromAddress MySystem@example.com
setx Logging__0__Args__ToAddress SRE@example.com
setx Logging__1__Name ToConsole
setx Logging__1__Level Information

Zmienne środowiskowe ustawiane w wygenerowanym pliku launchSettings.json

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym. Na przykład szablony internetowe ASP.NET Core generują plik launchSettings.json, który ustawia konfigurację punktu końcowego na:

"applicationUrl": "https://localhost:5001;http://localhost:5000"

Skonfigurowanie applicationUrl ustawia zmienną środowiskową ASPNETCORE_URLS i zastępuje wartości ustawione w środowisku.

Stosowanie opcji ucieczki w zmiennych środowiskowych w systemie Windows

W systemie Linux należy zastosować opcję ucieczki dla zmiennych środowiskowych URL, aby element systemd mógł je przeanalizować. Użyj narzędzia systemd-escape systemu Linux, które daje w wyniku http:--localhost:5001

groot@terminus:~$ systemd-escape http://localhost:5001
http:--localhost:5001

Wyświetlanie zmiennych środowiskowych

Poniższy kod wyświetla wartości i zmienne środowiskowe podczas uruchamiania aplikacji, co może być przydatne podczas debugowania ustawień środowiska:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

foreach (var c in builder.Configuration.AsEnumerable())
{
    Console.WriteLine(c.Key + " = " + c.Value);
}

Wiersz polecenia

Używając konfiguracji domyślnej, element CommandLineConfigurationProvider ładuje konfigurację z par klucz-wartość argumentów wiersza polecenia po następujących źródłach konfiguracji:

  • Pliki appsettings.json i appsettings.{Environment}.json.
  • Wpisy tajne aplikacji w środowisku deweloperskim.
  • Zmienne środowiskowe.

Domyślnie wartości konfiguracji ustawione w wierszu polecenia zastępują wartości konfiguracji ustawione w ramach wszystkich innych dostawców konfiguracji.

Argumenty wiersza polecenia

Następujące polecenie ustawia klucze i wartości przy użyciu =:

dotnet run MyKey="Using =" Position:Title=Cmd Position:Name=Cmd_Rick

Następujące polecenie ustawia klucze i wartości przy użyciu /:

dotnet run /MyKey "Using /" /Position:Title=Cmd /Position:Name=Cmd_Rick

Następujące polecenie ustawia klucze i wartości przy użyciu --:

dotnet run --MyKey "Using --" --Position:Title=Cmd --Position:Name=Cmd_Rick

Wartość klucza:

  • Musi następować po = lub klucz musi mieć prefiks -- albo /, gdy wartość następuje po spacji.
  • Nie jest wymagana w przypadku użycia elementu =. Na przykład MySetting=.

W tym samym poleceniu nie mieszaj par klucz-wartość argumentu wiersza polecenia, które używają elementu =, z parami klucz-wartość, które używają spacji.

Mapowania przełączników

Mapowania przełączników umożliwiają stosowanie logiki zastępowania nazwy klucza. Udostępnij słownik zamienników przełączników metodzie AddCommandLine.

Jeśli używasz słownika mapowań przełączników, jest on sprawdzany pod kątem klucza zgodnego z kluczem dostarczonym przez argument wiersza polecenia. Po znalezieniu klucza wiersza polecenia w słowniku wartość ze słownika jest przekazywana z powrotem w celu ustawienia pary klucz-wartość w konfiguracji aplikacji. Mapowanie przełącznika jest wymagane dla dowolnego klucza wiersza polecenia poprzedzonego pojedynczym łącznikiem (-).

Reguły dotyczące kluczy słownika mapowania przełączników:

  • Przełączniki muszą zaczynać się od - lub --.
  • Słownik mapowań przełącznika nie może zawierać zduplikowanych kluczy.

Aby używać słownika mapowań przełączników, przekaż go do wywołania do AddCommandLine:


var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var switchMappings = new Dictionary<string, string>()
         {
             { "-k1", "key1" },
             { "-k2", "key2" },
             { "--alt3", "key3" },
             { "--alt4", "key4" },
             { "--alt5", "key5" },
             { "--alt6", "key6" },
         };

builder.Configuration.AddCommandLine(args, switchMappings);

var app = builder.Build();

Uruchom następujące polecenie, aby przetestować zamiennik klucza:

dotnet run -k1 value1 -k2 value2 --alt3=value2 /alt4=value3 --alt5 value5 /alt6 value6

Poniższy kod pokazuje wartości zastąpionych kluczy:

public class Test3Model : PageModel
{
    private readonly IConfiguration Config;

    public Test3Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        return Content(
                $"Key1: '{Config["Key1"]}'\n" +
                $"Key2: '{Config["Key2"]}'\n" +
                $"Key3: '{Config["Key3"]}'\n" +
                $"Key4: '{Config["Key4"]}'\n" +
                $"Key5: '{Config["Key5"]}'\n" +
                $"Key6: '{Config["Key6"]}'");
    }
}

W przypadku aplikacji korzystających z mapowań przełączników wywołanie do CreateDefaultBuilder nie powinno przekazywać argumentów. Wywołanie polecenia AddCommandLine w metodzie CreateDefaultBuilder nie uwzględnia mapowanych przełączników i nie ma sposobu na przekazanie słownika mapowań przełączników do CreateDefaultBuilder. Rozwiązaniem nie jest przekazanie argumentów do metody CreateDefaultBuilder, ale zezwolenie umożliwia metodzie AddCommandLine w metodzie ConfigurationBuilder przetwarzanie zarówno argumentów, jak i słownika mapowania przełączników.

Ustawianie argumentów środowiska i wiersza polecenia w programie Visual Studio

Argumenty środowiska i wiersza polecenia można ustawić w programie Visual Studio w oknie dialogowym profilów uruchamiania:

  • W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz polecenie Właściwości.
  • Wybierz kartę Debugowanie > Ogólne i wybierz pozycję Otwórz interfejs użytkownika debugowania profilów uruchamiania.

Hierarchiczne dane konfiguracji

Interfejs API konfiguracji odczytuje hierarchiczne dane konfiguracji, spłaszczając dane hierarchiczne przy użyciu ogranicznika w kluczach konfiguracji.

Przykładowy materiał do pobrania zawiera następujący plik appsettings.json:

{
  "Position": {
    "Title": "Editor",
    "Name": "Joe Smith"
  },
  "MyKey": "My appsettings.json Value",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Poniższy kod z przykładowego materiału do pobrania powoduje wyświetlenie kilku ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Preferowanym sposobem odczytywania hierarchicznych danych konfiguracji jest użycie wzorca opcji. Aby uzyskać więcej informacji, zapoznaj się z sekcją Tworzenie powiązania hierarchicznych danych konfiguracji w tym dokumencie.

Metody GetSection i GetChildren są dostępne w przypadki izolowania sesji i elementów podrzędnych sekcji w danych konfiguracji. Te metody zostały dalej opisane w sekcji GetSection, GetChildren i Exists.

Klucze i wartości konfiguracji

Klucze konfiguracji:

  • Nie uwzględniają wielkości liter. Na przykład ConnectionString i connectionstring są traktowane jako klucze równoważne.
  • Jeśli klucz i wartość zostaną ustawione w obrębie więcej niż jednego dostawcy konfiguracji, będzie używana wartość z ostatniego dodanego dostawcy. Aby uzyskać więcej informacji, zobacz Konfiguracja domyślna.
  • Klucze hierarchiczne
    • W interfejsie API konfiguracji separator w postaci dwukropka (:) działa na wszystkich platformach.
    • W zmiennych środowiskowych separator w postaci dwukropka może nie działać na wszystkich platformach. Podwójne podkreślenie (__) jest obsługiwane na wszystkich platformach i jest automatycznie konwertowane na dwukropek (:).
    • W usłudze Azure Key Vault klucze hierarchiczne używają separatora --. Dostawca konfiguracji usługi Azure Key Vault automatycznie zastępuje znak -- znakiem :, gdy wpisy tajne są ładowane do konfiguracji aplikacji.
  • Element ConfigurationBinder obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Tworzenie powiązań tablic jest opisane w sekcji Tworzenie powiązania tablicy z klasą.

Wartości konfiguracji:

  • Są ciągami.
  • Wartości null nie mogą być przechowywane w konfiguracji ani powiązane z obiektami.

Dostawcy konfiguracji

W poniższej tabeli przedstawiono dostawców konfiguracji dostępnych dla aplikacji platformy ASP.NET Core.

Dostawca Dostarcza konfigurację z
Dostawca konfiguracji usługi Azure Key Vault Azure Key Vault
Dostawca konfiguracji aplikacji platformy Azure Azure App Configuration
Dostawca konfiguracji wiersza polecenia Parametry wiersza polecenia
Niestandardowy dostawca konfiguracji Źródło niestandardowe
Dostawca konfiguracji zmiennych środowiskowych Zmienne środowiskowe
Dostawca konfiguracji plików Pliki INI, JSON i XML
Dostawca konfiguracji typu „klucz na plik” Pliki katalogów
Dostawca konfiguracji pamięci Kolekcje w pamięci
Wpisy tajne użytkownika Plik w katalogu profilów użytkownika

Źródła konfiguracji są odczytywane w kolejności, w której określono odpowiednich dostawców konfiguracji. Uporządkuj dostawców konfiguracji w kodzie, aby dopasować priorytety do bazowych źródeł konfiguracji, których wymaga aplikacja.

Typowa sekwencja dostawców konfiguracji to:

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. Wpisy tajne użytkownika
  4. Zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych.
  5. Argumenty wiersza polecenia, które korzystają z dostawcy konfiguracji wiersza polecenia.

Powszechną praktyką jest dodawanie dostawcy konfiguracji wiersza polecenia jako ostatniego w serii dostawców, aby zezwolić argumentom wiersza polecenia na zastępowanie konfiguracji ustawionych przez innych dostawców.

Poprzednia sekwencja dostawców jest używana w konfiguracji domyślnej.

Prefiksy parametrów połączenia

Interfejs API konfiguracji ma specjalne reguły przetwarzania dla czterech zmiennych środowiskowych parametrów połączenia. Te parametry połączenia są uwzględniane podczas konfigurowania parametrów połączenia platformy Azure dla środowiska aplikacji. Zmienne środowiskowe z prefiksami pokazanymi w tabeli są ładowane do aplikacji z użyciem konfiguracji domyślnej lub gdy prefiks nie zostanie dostarczony do elementu AddEnvironmentVariables.

Prefiks parametrów połączenia Dostawca
CUSTOMCONNSTR_ Dostawca niestandardowy
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

Gdy zmienna środowiskowa zostanie odnaleziona i załadowana do konfiguracji z dowolnym z czterech prefiksów pokazanych w tabeli:

  • Klucz konfiguracji jest tworzony przez usunięcie prefiksu zmiennej środowiskowej i dodanie sekcji klucza konfiguracji (ConnectionStrings).
  • Tworzona jest nowa para klucz-wartość konfiguracji, która reprezentuje dostawcę połączenia z bazą danych (z wyjątkiem elementu CUSTOMCONNSTR_, który nie ma podanego dostawcy).
Klucz zmiennej środowiskowej Przekonwertowany klucz konfiguracji Wpis konfiguracji dostawcy
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} Wpis konfiguracji nie został utworzony.
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} Klucz: ConnectionStrings:{KEY}_ProviderName:
Wartość: System.Data.SqlClient

Dostawca konfiguracji plików

FileConfigurationProvider to klasa bazowa na potrzeby ładowania konfiguracji z systemu plików. Następujący dostawcy konfiguracji pochodzą z obiektu FileConfigurationProvider:

Dostawca konfiguracji plików INI

Element IniConfigurationProvider ładuje konfigurację z par klucz-wartość pliku INI w czasie wykonywania.

Poniższy kod dodaje kilku dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
    .AddIniFile($"MyIniConfig.{builder.Environment.EnvironmentName}.ini",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

W poprzednim kodzie ustawienia w plikach MyIniConfig.ini i MyIniConfig.{Environment}.ini są zastępowane przez ustawienia w następujących obszarach:

Przykładowy materiał do pobrania zawiera następujący plik MyIniConfig.ini:

MyKey="MyIniConfig.ini Value"

[Position]
Title="My INI Config title"
Name="My INI Config name"

[Logging:LogLevel]
Default=Information
Microsoft=Warning

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Dostawca konfiguracji plików JSON

Element JsonConfigurationProvider ładuje konfigurację z par klucz-wartość pliku JSON.

Przeciążenia mogą wskazywać, czy:

  • Plik jest opcjonalny.
  • Konfiguracja zostanie ponownie załadowana, jeśli plik się zmieni.

Spójrzmy na poniższy kod:

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile("MyConfig.json",
        optional: true,
        reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

Powyższy kod ma następujące działanie:

Zazwyczaj nie chcesz, aby niestandardowy plik JSON zastępował wartości ustawione w obrębie dostawcy konfiguracji zmiennych środowiskowych i dostawcy konfiguracji wiersza polecenia.

Dostawca konfiguracji plików XML

Element XmlConfigurationProvider ładuje konfigurację z par klucz-wartość pliku XML w czasie wykonywania.

Poniższy kod dodaje kilku dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
    .AddXmlFile($"MyXMLFile.{builder.Environment.EnvironmentName}.xml",
                optional: true, reloadOnChange: true);

builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

W poprzednim kodzie ustawienia w plikach MyXMLFile.xml i MyXMLFile.{Environment}.xml są zastępowane przez ustawienia w następujących obszarach:

Przykładowy materiał do pobrania zawiera następujący plik MyXMLFile.xml:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <MyKey>MyXMLFile Value</MyKey>
  <Position>
    <Title>Title from  MyXMLFile</Title>
    <Name>Name from MyXMLFile</Name>
  </Position>
  <Logging>
    <LogLevel>
      <Default>Information</Default>
      <Microsoft>Warning</Microsoft>
    </LogLevel>
  </Logging>
</configuration>

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie kilku poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

Powtarzające się elementy, które używają tej samej nazwy elementu, działają, jeśli do rozróżniania elementów jest używany atrybut name:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <section name="section0">
    <key name="key0">value 00</key>
    <key name="key1">value 01</key>
  </section>
  <section name="section1">
    <key name="key0">value 10</key>
    <key name="key1">value 11</key>
  </section>
</configuration>

Poniższy kod odczytuje poprzedni plik konfiguracji i wyświetla klucze oraz wartości:

public class IndexModel : PageModel
{
    private readonly IConfiguration Configuration;

    public IndexModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var key00 = "section:section0:key:key0";
        var key01 = "section:section0:key:key1";
        var key10 = "section:section1:key:key0";
        var key11 = "section:section1:key:key1";

        var val00 = Configuration[key00];
        var val01 = Configuration[key01];
        var val10 = Configuration[key10];
        var val11 = Configuration[key11];

        return Content($"{key00} value: {val00} \n" +
                       $"{key01} value: {val01} \n" +
                       $"{key10} value: {val10} \n" +
                       $"{key10} value: {val11} \n"
                       );
    }
}

Atrybuty mogą być używane do podawania wartości:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <key attribute="value" />
  <section>
    <key attribute="value" />
  </section>
</configuration>

Poprzedni plik konfiguracji ładuje następujące klucze za pomocą elementu value:

  • key:attribute
  • section:key:attribute

Dostawca konfiguracji typu „klucz na plik”

Element KeyPerFileConfigurationProvider używa plików katalogu jako par klucz-wartość konfiguracji. Klucz to nazwa pliku. Wartość obejmuje zawartość pliku. Dostawca konfiguracji typu „klucz na plik” jest używany w scenariuszach hostingu platformy Docker.

Aby aktywować konfigurację typu „klucz na plik”, wywołaj metodę rozszerzenia AddKeyPerFile w wystąpieniu ConfigurationBuilder. Ścieżka directoryPath do plików musi być ścieżką bezwzględną.

Przeciążenia uniemożliwiają określanie następujących elementów:

  • Delegat Action<KeyPerFileConfigurationSource>, który konfiguruje źródło.
  • Czy katalog jest opcjonalny oraz ścieżka do tego katalogu.

Podwójne podkreślenie (__) jest używane jako ogranicznik klucza konfiguracji w nazwach plików. Na przykład nazwa pliku Logging__LogLevel__System tworzy klucz konfiguracji Logging:LogLevel:System.

Wywołaj ConfigureAppConfiguration podczas kompilowania hosta, aby określić konfigurację aplikacji:

.ConfigureAppConfiguration((hostingContext, config) =>
{
    var path = Path.Combine(
        Directory.GetCurrentDirectory(), "path/to/files");
    config.AddKeyPerFile(directoryPath: path, optional: true);
})

Dostawca konfiguracji pamięci

Element MemoryConfigurationProvider używa kolekcji w pamięci jako par klucz-wartość konfiguracji.

Poniższy kod dodaje kolekcję pamięci do systemu konfiguracji:

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.AddCommandLine(args);

builder.Services.AddRazorPages();

var app = builder.Build();

Poniższy kod z przykładowego pliku do pobrania powoduje wyświetlenie poprzednich ustawień konfiguracji:

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n" +
                       $"Title: {title} \n" +
                       $"Name: {name} \n" +
                       $"Default Log Level: {defaultLogLevel}");
    }
}

W poprzednim kodzie element config.AddInMemoryCollection(Dict) jest dodawany po domyślnych dostawcach konfiguracji. Aby uzyskać przykład zamawiania dostawców konfiguracji, zobacz artykuł Dostawca konfiguracji JSON.

Inny przykład korzystający z elementu MemoryConfigurationProvider można znaleźć w sekcji Tworzenie powiązania tablicy.

Konfiguracja punktu końcowego Kestrel

Konfiguracja specyficzna dla punktu końcowego Kestrel zastępuje konfiguracje punktów końcowych między serwerami. Konfiguracje punktów końcowych między serwerami:

Rozważ następujący plik appsettings.json użyty w aplikacji internetowej ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Gdy poprzednia wyróżniona adiustacja jest używana w aplikacji internetowej ASP.NET Core oraz aplikacja jest uruchamiana w wierszu polecenia z użyciem następującej konfiguracji punktu końcowego między serwerami:

dotnet run --urls="https://localhost:7777"

Kestrel wiąże się z punktem końcowym skonfigurowanym specjalnie dla Kestrel w pliku appsettings.json (https://localhost:9999), a nie https://localhost:7777.

Rozważ punkt końcowy specyficzny dla Kestrel, który skonfigurowano jako zmienną środowiskową:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

W poprzedniej zmiennej środowiskowej Https to nazwa punktu końcowego specyficznego dla Kestrel. Poprzedni plik appsettings.json definiuje również punkt końcowy specyficzny dla Kestrel o nazwie Https. Domyślnie zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych są odczytywane po appsettings.{Environment}.json, dlatego poprzednia zmienna środowiskowa jest używana dla punktu końcowego Https.

GetValue

ConfigurationBinder.GetValue wyodrębnia pojedynczą wartość z konfiguracji przy użyciu określonego klucza i konwertuje ją na określony typ:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

Jeśli w poprzednim kodzie element NumberKey nie zostanie znaleziony w konfiguracji, zostanie użyta wartość domyślna 99.

GetSection, GetChildren i Exists

W poniższych przykładach użyj następującego pliku MySubsection.json:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

Następujący kod dodaje element MySubsection.json do dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MySubsection.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection zwraca podsekcję konfiguracji z określonym kluczem podsekcji.

Poniższy kod zwraca wartości dla section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

Poniższy kod zwraca wartości dla section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nigdy nie zwraca null. Jeśli nie znaleziono pasującej sekcji, jest zwracany pusty element IConfigurationSection.

Gdy GetSection zwraca pasującą sekcję, element Value nie jest wypełniany. Jeśli sekcja istnieje, zwracane są elementy Key i Path.

GetChildren i Exists

Poniższy kod wywołuje IConfiguration.GetChildren i zwraca wartości dla section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = "";
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

Poprzedni kod wywołuje ConfigurationExtensions.Exists, aby sprawdzić, czy sekcja istnieje:

Tworzenie tablicy

Element ConfigurationBinder.Bind obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Format tablicy, który uwidacznia numeryczny segment klucza, ma możliwość tworzenia powiązania tablicy z tablicą klas POCO.

Rozważ użycie elementu MyArray.json z przykładowego pliku do pobrania:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

Następujący kod dodaje element MyArray.json do dostawców konfiguracji:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddJsonFile("MyArray.json",
                 optional: true,
                 reloadOnChange: true);

builder.Services.AddRazorPages();

var app = builder.Build();

Następujący kod odczytuje konfigurację i wyświetla wartości:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample? _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
       _array = Config.GetSection("array").Get<ArrayExample>();
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }
        string s = String.Empty;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}
public class ArrayExample
{
    public string[]? Entries { get; set; } 
}

Poprzedni kod zwraca następujące dane wyjściowe:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

W poprzednich danych wyjściowych indeks 3 ma wartość value40, odpowiadającą wartości "4": "value40", w MyArray.json. Indeksy tablicy powiązanej są ciągłe i nie są powiązane z indeksem kluczy konfiguracji. Integrator nie może powiązać wartości null ani tworzyć wpisów null w powiązanych obiektach.

Niestandardowy dostawca konfiguracji

Przykładowa aplikacja pokazuje, jak utworzyć podstawowego dostawcę konfiguracji, który odczytuje pary klucz-wartość konfiguracji z bazy danych przy użyciu zestawu technologii Entity Framework (EF).

Dostawca ma następujące charakterystyki:

  • Baza danych EF w pamięci jest używana podczas pokazów. Aby używać bazy danych, która wymaga parametrów połączenia, zaimplementuj pomocniczy obiekt ConfigurationBuilder, aby dostarczyć parametry połączenia od innego dostawcy konfiguracji.
  • Dostawca odczytuje tabelę bazy danych do konfiguracji w momencie uruchamiania. Dostawca nie wykonuje zapytań dotyczących bazy danych na podstawie poszczególnych kluczy.
  • Ponowne ładowanie przy zmianie nie jest implementowane, dlatego aktualizacja bazy danych po uruchomieniu aplikacji nie ma wpływu na konfigurację aplikacji.

Zdefiniuj jednostkę EFConfigurationValue służącą do przechowywania wartości konfiguracji w bazie danych.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; } = String.Empty;
    public string Value { get; set; } = String.Empty;
}

Dodaj element EFConfigurationContext służący do przechowywania skonfigurowanych wartości i uzyskiwania do nich dostępu.

EFConfigurationProvider/EFConfigurationContext.cs:

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}

Utwórz klasę, która implementuje IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) => _optionsAction = optionsAction;

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new EFConfigurationProvider(_optionsAction);
}

Utwórz niestandardowego dostawcę konfiguracji, stosując dziedziczenie z ConfigurationProvider. Dostawca konfiguracji inicjuje bazę danych, gdy jest ona pusta. Ponieważ w kluczach konfiguracji nie jest uwzględniana wielkość liter, słownik używany do inicjowania bazy danych jest tworzony przy użyciu modułu porównywania bez uwzględniania wielkości liter (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            if (dbContext == null || dbContext.Values == null)
            {
                throw new Exception("Null DB context");
            }
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues =
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                    { "quote1", "I aim to misbehave." },
                    { "quote2", "I swallowed a bug." },
                    { "quote3", "You can't stop the signal, Mal." }
            };

        if (dbContext == null || dbContext.Values == null)
        {
            throw new Exception("Null DB context");
        }

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue
            {
                Id = kvp.Key,
                Value = kvp.Value
            })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Metoda rozszerzenia AddEFConfiguration zezwala na dodawanie źródła konfiguracji do elementu ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
               this IConfigurationBuilder builder,
               Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

W poniższym kodzie pokazano sposób użycia niestandardowego elementu EFConfigurationProvider w Program.cs:

//using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEFConfiguration(
    opt => opt.UseInMemoryDatabase("InMemoryDb"));

var app = builder.Build();

app.Run();

Konfiguracja dostępu za pomocą wstrzykiwania zależności

Konfigurację można wstrzykiwać do usług przy użyciu funkcji wstrzykiwania zależności, rozwiązując usługę IConfiguration:

public class Service
{
    private readonly IConfiguration _config;

    public Service(IConfiguration config) =>
        _config = config;

    public void DoSomething()
    {
        var configSettingValue = _config["ConfigSetting"];

        // ...
    }
}

Aby uzyskać informacje na temat uzyskiwania dostępu do wartości przy użyciu elementu IConfiguration, zobacz sekcje GetValue oraz GetSection, GetChildren i Exists w tym artykule.

Konfiguracja dostępu w usłudze Razor Pages

Poniższy kod wyświetla dane konfiguracji na stronie usługi Razor Pages:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

W poniższym kodzie element MyOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(
    builder.Configuration.GetSection("MyOptions"));

var app = builder.Build();

Następująca adiustacja używa dyrektywy @injectRazor do rozpoznawania i wyświetlania wartości opcji:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@using SampleApp.Models
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Konfiguracja dostępu w pliku widoku MVC

Poniższy kod wyświetla dane konfiguracji w widoku MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Konfiguracja dostępu w Program.cs

Następujący kod uzyskuje dostęp do konfiguracji w pliku Program.cs.

var builder = WebApplication.CreateBuilder(args);

var key1 = builder.Configuration.GetValue<string>("KeyOne");

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

var key2 = app.Configuration.GetValue<int>("KeyTwo");
var key3 = app.Configuration.GetValue<bool>("KeyThree");

app.Logger.LogInformation("KeyOne: {KeyOne}", key1);
app.Logger.LogInformation("KeyTwo: {KeyTwo}", key2);
app.Logger.LogInformation("KeyThree: {KeyThree}", key3);

app.Run();

W appsettings.json pliku dla poprzedniego przykładu:

{
  ...
  "KeyOne": "Key One Value",
  "KeyTwo": 1999,
  "KeyThree": true
}

Konfigurowanie opcji za pomocą delegata

Opcje skonfigurowane w ramach delegata zastępują wartości ustawione w obrębie dostawców konfiguracji.

W poniższym kodzie usługa IConfigureOptions<TOptions> jest dodawana do kontenera usług. Używa ona delegata do konfigurowania wartości dla MyOptions:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.Configure<MyOptions>(myOptions =>
{
    myOptions.Option1 = "Value configured in delegate";
    myOptions.Option2 = 500;
});

var app = builder.Build();

Poniższy kod wyświetla wartości opcji:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

W poprzednim przykładzie wartości parametrów Option1 i Option2 są określane w obszarze appsettings.json, a następnie zastępowane przez skonfigurowanego delegata.

Konfiguracja hosta a konfiguracja aplikacji

Przed skonfigurowaniem i uruchomieniem aplikacji następuje skonfigurowanie i uruchomienie hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Zarówno aplikacja, jak i host są konfigurowane przy użyciu dostawców konfiguracji opisanych w tym temacie. Pary klucz-wartość konfiguracji hosta są również uwzględniane w konfiguracji aplikacji. Aby uzyskać więcej informacji na temat sposobu używania dostawców konfiguracji podczas kompilowania hosta oraz wpływu źródeł konfiguracji na konfigurację hosta, zapoznaj się z omówieniem podstaw platformy ASP.NET Core.

Domyślna konfiguracja hosta

Szczegóły konfiguracji domy.ślnej w przypadku korzystania z hosta internetowego można znaleźć w sekcji dotyczącej platformy ASP.NET Core w wersji 2.2 w tym temacie.

  • Konfiguracja hosta jest dostarczana z:
  • Zostanie ustanowiona domyślna konfiguracja hosta sieci Web (ConfigureWebHostDefaults):
    • Element Kestrel jest używany jako serwer internetowy i konfigurowany przy użyciu dostawców konfiguracji aplikacji.
    • Dodaj oprogramowanie pośredniczące do filtrowania hostów.
    • Dodaj oprogramowanie pośredniczące powiązane z przekazanymi nagłówkami, jeśli zmienna środowiskowa ASPNETCORE_FORWARDEDHEADERS_ENABLED została ustawiona na true.
    • Włącz integrację usług IIS.

Inna konfiguracja

Ten temat dotyczy tylko konfiguracji aplikacji. Inne aspekty uruchamiania i hostowania aplikacji platformy ASP.NET Core są konfigurowane przy użyciu plików konfiguracji, których nie omawiamy w tym temacie:

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym.

Aby uzyskać więcej informacji na temat migrowania konfiguracji aplikacji z wcześniejszych wersji ASP.NET, zobacz Aktualizowanie z ASP.NET do ASP.NET Core.

Dodawanie konfiguracji z zestawu zewnętrznego

Implementacja IHostingStartup umożliwia dodawanie ulepszeń do aplikacji podczas uruchamiania z zestawu zewnętrznego znajdującego się poza klasą Startup aplikacji. Więcej informacji można znaleźć w temacie Korzystanie z hostowania zestawów startowych na platformie ASP.NET Core.

Dodatkowe zasoby

Konfiguracja punktu końcowego Kestrel

Konfiguracja specyficzna dla punktu końcowego Kestrel zastępuje konfiguracje punktów końcowych między serwerami. Konfiguracje punktów końcowych między serwerami:

Rozważ następujący plik appsettings.json użyty w aplikacji internetowej ASP.NET Core:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:9999"
      }
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
} 

Gdy poprzednia wyróżniona adiustacja jest używana w aplikacji internetowej ASP.NET Core oraz aplikacja jest uruchamiana w wierszu polecenia z użyciem następującej konfiguracji punktu końcowego między serwerami:

dotnet run --urls="https://localhost:7777"

Kestrel wiąże się z punktem końcowym skonfigurowanym specjalnie dla Kestrel w pliku appsettings.json (https://localhost:9999), a nie https://localhost:7777.

Rozważ punkt końcowy specyficzny dla Kestrel, który skonfigurowano jako zmienną środowiskową:

set Kestrel__Endpoints__Https__Url=https://localhost:8888

W poprzedniej zmiennej środowiskowej Https to nazwa punktu końcowego specyficznego dla Kestrel. Poprzedni plik appsettings.json definiuje również punkt końcowy specyficzny dla Kestrel o nazwie Https. Domyślnie zmienne środowiskowe korzystające z dostawcy konfiguracji zmiennych środowiskowych są odczytywane po appsettings.{Environment}.json, dlatego poprzednia zmienna środowiskowa jest używana dla punktu końcowego Https.

GetValue

ConfigurationBinder.GetValue wyodrębnia pojedynczą wartość z konfiguracji przy użyciu określonego klucza i konwertuje ją na określony typ. Ta metoda to metoda rozszerzenia dla elementu IConfiguration:

public class TestNumModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestNumModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var number = Configuration.GetValue<int>("NumberKey", 99);
        return Content($"{number}");
    }
}

Jeśli w poprzednim kodzie element NumberKey nie zostanie znaleziony w konfiguracji, zostanie użyta wartość domyślna 99.

GetSection, GetChildren i Exists

W poniższych przykładach użyj następującego pliku MySubsection.json:

{
  "section0": {
    "key0": "value00",
    "key1": "value01"
  },
  "section1": {
    "key0": "value10",
    "key1": "value11"
  },
  "section2": {
    "subsection0": {
      "key0": "value200",
      "key1": "value201"
    },
    "subsection1": {
      "key0": "value210",
      "key1": "value211"
    }
  }
}

Następujący kod dodaje element MySubsection.json do dostawców konfiguracji:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MySubsection.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

GetSection

IConfiguration.GetSection zwraca podsekcję konfiguracji z określonym kluczem podsekcji.

Poniższy kod zwraca wartości dla section1:

public class TestSectionModel : PageModel
{
    private readonly IConfiguration Config;

    public TestSectionModel(IConfiguration configuration)
    {
        Config = configuration.GetSection("section1");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section1:key0: '{Config["key0"]}'\n" +
                $"section1:key1: '{Config["key1"]}'");
    }
}

Poniższy kod zwraca wartości dla section2:subsection0:

public class TestSection2Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection2Model(IConfiguration configuration)
    {
        Config = configuration.GetSection("section2:subsection0");
    }

    public ContentResult OnGet()
    {
        return Content(
                $"section2:subsection0:key0 '{Config["key0"]}'\n" +
                $"section2:subsection0:key1:'{Config["key1"]}'");
    }
}

GetSection nigdy nie zwraca null. Jeśli nie znaleziono pasującej sekcji, jest zwracany pusty element IConfigurationSection.

Gdy GetSection zwraca pasującą sekcję, element Value nie jest wypełniany. Jeśli sekcja istnieje, zwracane są elementy Key i Path.

GetChildren i Exists

Poniższy kod wywołuje IConfiguration.GetChildren i zwraca wartości dla section2:subsection0:

public class TestSection4Model : PageModel
{
    private readonly IConfiguration Config;

    public TestSection4Model(IConfiguration configuration)
    {
        Config = configuration;
    }

    public ContentResult OnGet()
    {
        string s = null;
        var selection = Config.GetSection("section2");
        if (!selection.Exists())
        {
            throw new System.Exception("section2 does not exist.");
        }
        var children = selection.GetChildren();

        foreach (var subSection in children)
        {
            int i = 0;
            var key1 = subSection.Key + ":key" + i++.ToString();
            var key2 = subSection.Key + ":key" + i.ToString();
            s += key1 + " value: " + selection[key1] + "\n";
            s += key2 + " value: " + selection[key2] + "\n";
        }
        return Content(s);
    }
}

Poprzedni kod wywołuje ConfigurationExtensions.Exists, aby sprawdzić, czy sekcja istnieje:

Tworzenie tablicy

Element ConfigurationBinder.Bind obsługuje tworzenie powiązań tablic z obiektami przy użyciu indeksów tablic w kluczach konfiguracji. Format tablicy, który uwidacznia numeryczny segment klucza, ma możliwość tworzenia powiązania tablicy z tablicą klas POCO.

Rozważ użycie elementu MyArray.json z przykładowego pliku do pobrania:

{
  "array": {
    "entries": {
      "0": "value00",
      "1": "value10",
      "2": "value20",
      "4": "value40",
      "5": "value50"
    }
  }
}

Następujący kod dodaje element MyArray.json do dostawców konfiguracji:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("MyArray.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Następujący kod odczytuje konfigurację i wyświetla wartości:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

Poprzedni kod zwraca następujące dane wyjściowe:

Index: 0  Value: value00
Index: 1  Value: value10
Index: 2  Value: value20
Index: 3  Value: value40
Index: 4  Value: value50

W poprzednich danych wyjściowych indeks 3 ma wartość value40, odpowiadającą wartości "4": "value40", w MyArray.json. Indeksy tablicy powiązanej są ciągłe i nie są powiązane z indeksem kluczy konfiguracji. Integrator nie może powiązać wartości null ani tworzyć wpisów null w powiązanych obiektach.

Poniższy kod ładuje konfigurację array:entries przy użyciu metody rozszerzenia AddInMemoryCollection:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

Poniższy kod odczytuje konfigurację w obszarze arrayDictDictionary i wyświetla wartości:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

Poprzedni kod zwraca następujące dane wyjściowe:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value4
Index: 4  Value: value5

Indeks 3 w powiązanych obiektach przechowuje dane konfiguracji dla klucza konfiguracji array:4 i jego wartości value4. W przypadku tworzenia powiązania danych konfiguracji zawierających tablicę indeksy w kluczach konfiguracji są używane do iterowania danych podczas tworzenia obiektu. Wartości null nie można przechowywać w danych konfiguracji, a wpis o wartości null nie jest tworzony w powiązanym obiekcie, gdy tablica w kluczach konfiguracji pomija co najmniej jeden indeks.

Brakujący element konfiguracji dla indeksu 3 można dostarczyć przed utworzeniem powiązania z wystąpieniem ArrayExample przez dowolnego dostawcę konfiguracji, który odczytuje parę klucz-wartość w indeksie 3. Sprawdź poniższy plik Value3.json z przykładowych materiałów do pobrania:

{
  "array:entries:3": "value3"
}

Poniższy kod zawiera konfigurację pliku Value3.json i elementu arrayDictDictionary:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var arrayDict = new Dictionary<string, string>
        {
            {"array:entries:0", "value0"},
            {"array:entries:1", "value1"},
            {"array:entries:2", "value2"},
            //              3   Skipped
            {"array:entries:4", "value4"},
            {"array:entries:5", "value5"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(arrayDict);
                config.AddJsonFile("Value3.json",
                                    optional: false, reloadOnChange: false);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

Poniższy kod odczytuje poprzednią konfigurację i wyświetla wartości:

public class ArrayModel : PageModel
{
    private readonly IConfiguration Config;
    public ArrayExample _array { get; private set; }

    public ArrayModel(IConfiguration config)
    {
        Config = config;
    }

    public ContentResult OnGet()
    {
        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = null;

        for (int j = 0; j < _array.Entries.Length; j++)
        {
            s += $"Index: {j}  Value:  {_array.Entries[j]} \n";
        }

        return Content(s);
    }
}

Poprzedni kod zwraca następujące dane wyjściowe:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value3
Index: 4  Value: value4
Index: 5  Value: value5

Niestandardowi dostawy konfiguracji nie muszą implementować powiązań tablicy.

Niestandardowy dostawca konfiguracji

Przykładowa aplikacja pokazuje, jak utworzyć podstawowego dostawcę konfiguracji, który odczytuje pary klucz-wartość konfiguracji z bazy danych przy użyciu zestawu technologii Entity Framework (EF).

Dostawca ma następujące charakterystyki:

  • Baza danych EF w pamięci jest używana podczas pokazów. Aby używać bazy danych, która wymaga parametrów połączenia, zaimplementuj pomocniczy obiekt ConfigurationBuilder, aby dostarczyć parametry połączenia od innego dostawcy konfiguracji.
  • Dostawca odczytuje tabelę bazy danych do konfiguracji w momencie uruchamiania. Dostawca nie wykonuje zapytań dotyczących bazy danych na podstawie poszczególnych kluczy.
  • Ponowne ładowanie przy zmianie nie jest implementowane, dlatego aktualizacja bazy danych po uruchomieniu aplikacji nie ma wpływu na konfigurację aplikacji.

Zdefiniuj jednostkę EFConfigurationValue służącą do przechowywania wartości konfiguracji w bazie danych.

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

Dodaj element EFConfigurationContext służący do przechowywania skonfigurowanych wartości i uzyskiwania do nich dostępu.

EFConfigurationProvider/EFConfigurationContext.cs:

// using Microsoft.EntityFrameworkCore;

public class EFConfigurationContext : DbContext
{
    public EFConfigurationContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<EFConfigurationValue> Values { get; set; }
}

Utwórz klasę, która implementuje IConfigurationSource.

EFConfigurationProvider/EFConfigurationSource.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationSource : IConfigurationSource
{
    private readonly Action<DbContextOptionsBuilder> _optionsAction;

    public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
    {
        _optionsAction = optionsAction;
    }

    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new EFConfigurationProvider(_optionsAction);
    }
}

Utwórz niestandardowego dostawcę konfiguracji, stosując dziedziczenie z ConfigurationProvider. Dostawca konfiguracji inicjuje bazę danych, gdy jest ona pusta. Ponieważ w kluczach konfiguracji nie jest uwzględniana wielkość liter, słownik używany do inicjowania bazy danych jest tworzony przy użyciu modułu porównywania bez uwzględniania wielkości liter (StringComparer.OrdinalIgnoreCase).

EFConfigurationProvider/EFConfigurationProvider.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public class EFConfigurationProvider : ConfigurationProvider
{
    public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
    {
        OptionsAction = optionsAction;
    }

    Action<DbContextOptionsBuilder> OptionsAction { get; }

    public override void Load()
    {
        var builder = new DbContextOptionsBuilder<EFConfigurationContext>();

        OptionsAction(builder);

        using (var dbContext = new EFConfigurationContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();

            Data = !dbContext.Values.Any()
                ? CreateAndSaveDefaultValues(dbContext)
                : dbContext.Values.ToDictionary(c => c.Id, c => c.Value);
        }
    }

    private static IDictionary<string, string> CreateAndSaveDefaultValues(
        EFConfigurationContext dbContext)
    {
        // Quotes (c)2005 Universal Pictures: Serenity
        // https://www.uphe.com/movies/serenity-2005
        var configValues = 
            new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "quote1", "I aim to misbehave." },
                { "quote2", "I swallowed a bug." },
                { "quote3", "You can't stop the signal, Mal." }
            };

        dbContext.Values.AddRange(configValues
            .Select(kvp => new EFConfigurationValue 
                {
                    Id = kvp.Key,
                    Value = kvp.Value
                })
            .ToArray());

        dbContext.SaveChanges();

        return configValues;
    }
}

Metoda rozszerzenia AddEFConfiguration zezwala na dodawanie źródła konfiguracji do elementu ConfigurationBuilder.

Extensions/EntityFrameworkExtensions.cs:

// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.Configuration;

public static class EntityFrameworkExtensions
{
    public static IConfigurationBuilder AddEFConfiguration(
        this IConfigurationBuilder builder, 
        Action<DbContextOptionsBuilder> optionsAction)
    {
        return builder.Add(new EFConfigurationSource(optionsAction));
    }
}

W poniższym kodzie pokazano sposób użycia niestandardowego elementu EFConfigurationProvider w Program.cs:

// using Microsoft.EntityFrameworkCore;

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEFConfiguration(
                options => options.UseInMemoryDatabase("InMemoryDb"));
        })

Konfiguracja dostępu przy uruchamianiu

Poniższy kod wyświetla dane konfiguracji w metodach Startup:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        Console.WriteLine($"MyKey : {Configuration["MyKey"]}");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        Console.WriteLine($"Position:Title : {Configuration["Position:Title"]}");

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

Przykład uzyskiwania dostępu do konfiguracji przy użyciu wygodnych metod uruchamiania został opisany w Uruchamianie aplikacji: wygodne metody.

Konfiguracja dostępu w usłudze Razor Pages

Poniższy kod wyświetla dane konfiguracji na stronie usługi Razor Pages:

@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

W poniższym kodzie element MyOptions jest dodawany do kontenera usługi przy użyciu Configure, a następnie jest tworzone jego powiązanie z konfiguracją:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));

    services.AddRazorPages();
}

Następująca adiustacja używa dyrektywy @injectRazor do rozpoznawania i wyświetlania wartości opcji:

@page
@model SampleApp.Pages.Test3Model
@using Microsoft.Extensions.Options
@inject IOptions<MyOptions> optionsAccessor


<p><b>Option1:</b> @optionsAccessor.Value.Option1</p>
<p><b>Option2:</b> @optionsAccessor.Value.Option2</p>

Konfiguracja dostępu w pliku widoku MVC

Poniższy kod wyświetla dane konfiguracji w widoku MVC:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

Configuration value for 'MyKey': @Configuration["MyKey"]

Konfigurowanie opcji za pomocą delegata

Opcje skonfigurowane w ramach delegata zastępują wartości ustawione w obrębie dostawców konfiguracji.

Konfigurowanie opcji przy użyciu delegata zostało przedstawione jako przykład 2 w przykładowej aplikacji.

W poniższym kodzie usługa IConfigureOptions<TOptions> jest dodawana do kontenera usług. Używa ona delegata do konfigurowania wartości dla MyOptions:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.Option1 = "Value configured in delegate";
        myOptions.Option2 = 500;
    });

    services.AddRazorPages();
}

Poniższy kod wyświetla wartości opcji:

public class Test2Model : PageModel
{
    private readonly IOptions<MyOptions> _optionsDelegate;

    public Test2Model(IOptions<MyOptions> optionsDelegate )
    {
        _optionsDelegate = optionsDelegate;
    }

    public ContentResult OnGet()
    {
        return Content($"Option1: {_optionsDelegate.Value.Option1} \n" +
                       $"Option2: {_optionsDelegate.Value.Option2}");
    }
}

W poprzednim przykładzie wartości parametrów Option1 i Option2 są określane w obszarze appsettings.json, a następnie zastępowane przez skonfigurowanego delegata.

Konfiguracja hosta a konfiguracja aplikacji

Przed skonfigurowaniem i uruchomieniem aplikacji następuje skonfigurowanie i uruchomienie hosta. Host jest odpowiedzialny za zarządzanie uruchamianiem i okresem istnienia aplikacji. Zarówno aplikacja, jak i host są konfigurowane przy użyciu dostawców konfiguracji opisanych w tym temacie. Pary klucz-wartość konfiguracji hosta są również uwzględniane w konfiguracji aplikacji. Aby uzyskać więcej informacji na temat sposobu używania dostawców konfiguracji podczas kompilowania hosta oraz wpływu źródeł konfiguracji na konfigurację hosta, zapoznaj się z omówieniem podstaw platformy ASP.NET Core.

Domyślna konfiguracja hosta

Szczegóły konfiguracji domy.ślnej w przypadku korzystania z hosta internetowego można znaleźć w sekcji dotyczącej platformy ASP.NET Core w wersji 2.2 w tym temacie.

  • Konfiguracja hosta jest dostarczana z:
    • Zmienne środowiskowe z prefiksem DOTNET_ (na przykład DOTNET_ENVIRONMENT) korzystające z dostawcy konfiguracji zmiennych środowiskowych. Prefiks (DOTNET_) jest usuwany podczas ładowania par klucz-wartość konfiguracji.
    • Argumenty wiersza polecenia korzystające z dostawcy konfiguracji wiersza polecenia.
  • Zostanie ustanowiona domyślna konfiguracja hosta sieci Web (ConfigureWebHostDefaults):
    • Element Kestrel jest używany jako serwer internetowy i konfigurowany przy użyciu dostawców konfiguracji aplikacji.
    • Dodaj oprogramowanie pośredniczące do filtrowania hostów.
    • Dodaj oprogramowanie pośredniczące powiązane z przekazanymi nagłówkami, jeśli zmienna środowiskowa ASPNETCORE_FORWARDEDHEADERS_ENABLED została ustawiona na true.
    • Włącz integrację usług IIS.

Inna konfiguracja

Ten temat dotyczy tylko konfiguracji aplikacji. Inne aspekty uruchamiania i hostowania aplikacji platformy ASP.NET Core są konfigurowane przy użyciu plików konfiguracji, których nie omawiamy w tym temacie:

Zmienne środowiskowe ustawione w launchSettings.json zastępują zmienne ustawione w środowisku systemowym.

Aby uzyskać więcej informacji na temat migrowania konfiguracji aplikacji z wcześniejszych wersji ASP.NET, zobacz Aktualizowanie z ASP.NET do ASP.NET Core.

Dodawanie konfiguracji z zestawu zewnętrznego

Implementacja IHostingStartup umożliwia dodawanie ulepszeń do aplikacji podczas uruchamiania z zestawu zewnętrznego znajdującego się poza klasą Startup aplikacji. Więcej informacji można znaleźć w temacie Korzystanie z hostowania zestawów startowych na platformie ASP.NET Core.

Dodatkowe zasoby