ASP.NET Core の構成

作成者: Rick Anderson および Kirk Larkin

ASP.NET Core の構成は、1つまたは複数の構成プロバイダーを使用して実行されます。 構成プロバイダーは、以下のようなさまざまな構成ソースを使用して、キーと値のペアから構成データを読み取ります:

  • appsettings.json などの設定ファイル
  • 環境変数
  • Azure Key Vault
  • Azure App Configuration
  • コマンド ライン引数
  • インストール済みまたは作成済みのカスタム プロバイダー
  • ディレクトリ ファイル
  • メモリ内 .NET オブジェクト

このトピックでは ASP.NET Core の構成について説明します。 コンソール アプリでの構成の使用方法について詳しくは、.NET 構成に関する記事をご覧ください。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

既定の構成

dotnet new または Visual Studio で作成された ASP.NET Core の web アプリが、次のコードを生成します:

var builder = WebApplication.CreateBuilder(args);

CreateBuilder により、次の順序でアプリの既定の構成が提供されます。

  1. ChainedConfigurationProvider は:既存の IConfiguration をソースとして追加します。 既定の構成では、ホスト構成を追加し、アプリ 構成の最初のソースとして設定します。
  2. JSON 構成プロバイダーを使用する appsettings.json
  3. JSON 構成プロバイダーを使用する appsettings. Environmentjson。 たとえば、appsettings.Production_._json および appsettings.Development _._json
  4. Development 環境でアプリが実行される際の App シークレット
  5. 環境変数構成プロバイダーを使用する環境変数。
  6. コマンドライン構成プロバイダーを使用するコマンドライン引数。

後から追加される構成プロバイダーは、それ以前のキー設定をオーバーライドします。 たとえば、MyKeyappsettings.json と環境の両方で設定されている場合、環境の値が使用されます。 既定の構成プロバイダーを使用すると、コマンドライン構成プロバイダー が他のすべてのプロバイダーをオーバーライドします。

CreateBuilder の詳細については、既定のビルダー設定を参照してください。

以下のコードでは、追加した順に、有効な構成プロバイダーが表示されます:

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

appsettings.json

次の appsettings.json ファイルを考えてみます。

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

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

既定の JsonConfigurationProvider は、以下の順序で構成を読み込みます:

  1. appsettings.json
  2. appsettings. Environment .json:たとえば、appsettings.Production_._json および appsettings.Development _._json ファイル。 ファイルの環境バージョンは、IHostingEnvironment.EnvironmentNameに基づいて読み込まれます。 詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。

appsettings.Environment.json の値によって、 appsettings.json 内のキーがオーバーライドされます。 たとえば、既定では次のようになります:

  • 開発中は、appsettings.Development _._json 構成によって、 appsettings.json で見つかった値が上書きされます。
  • 運用環境では、appsettings.Production _._json 構成によって、 appsettings.json で見つかった値が上書きされます。 たとえば、Azure にアプリをデプロイする場合。

構成値を保証する必要がある場合は、「GetValue」を参照してください。 前の例では文字列が読み取られるだけで、既定値はサポートされていません。

既定の構成を利用する場合、reloadOnChange: trueappsettings.jsonappsettings. Environment .json ファイルを有効にすることができます。 アプリの開始 appsettings.jsonappsettings. Environment .json ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。

オプションパターンを使用して、階層型の構成データをバインドします

関連する構成値を読み取る方法としては、オプション パターンを使用することをお勧めします。 たとえば、以下の構成値を読み取るには、次のようにします:

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

次の PositionOptions クラスを作成します:

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

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

オプション クラス:

  • パラメーターのないパブリック コンストラクターを持った非抽象でなければなりません。
  • 型のパブリックな読み取り/書き込みプロパティは、すべてバインドされます。
  • フィールドはバインド されません。 上のコード Position はバインドされません。 Position プロパティは、クラスを構成プロバイダーにバインドするときに、アプリで文字列 "Position" をハードコーディングする必要をなくすために使用されます。

コード例を次に示します。

  • ConfigurationBinder.Bind を呼び出して、PositionOptions クラスを Position セクションにバインドします。
  • 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}");
    }
}

上のコードでは、アプリが開始された後の JSON 構成ファイルへの変更が既定で読み取られます。

ConfigurationBinder.Get<T> 指定された型をバインドして返します。 ConfigurationBinder.Get<T>ConfigurationBinder.Bind を使用するよりも便利な場合があります。 次のコードは、PositionOptions クラスで ConfigurationBinder.Get<T> を使用する方法を示しています:

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

上のコードでは、アプリが開始された後の JSON 構成ファイルへの変更が既定で読み取られます。

*オプション パターン _ を使用する際の別の方法として、Position セクションをバインドし、依存関係挿入サービスコンテナーに追加する方法があります。 次のコードでは、PositionOptions は <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure_> でサービスコンテナーに追加され、構成にバインドされます:

using ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

var app = builder.Build();

下記のコードは、上記のコードを使用して位置オプションを読み取ります:

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

上のコードでは、アプリが開始された後の JSON 構成ファイルへの変更は読み取られ ません。 アプリの開始後に変更を読み取るには、IOptionsSnapshot を使用します。

既定の構成を利用する場合、reloadOnChange: trueappsettings.jsonappsettings. Environment .json ファイルを有効にすることができます。 アプリの開始 appsettings.jsonappsettings. Environment .json ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。

追加の JSON 構成ファイルを追加する方法の詳細については、このドキュメント中の「JSON 構成プロバイダー」を参照してください。

サービス コレクションの結合

サービスを登録し、オプションを構成する次の ConfigureServices メソッドについて考えてみましょう。

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

関連する登録グループは、サービスを登録するための拡張メソッドに移動できます。 たとえば、構成サービスは次のクラスに追加されます。

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

残りのサービスは、同様のクラスに登録されます。 次の ConfigureServices メソッドでは、新しい拡張メソッドを使用してサービスを登録します。

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

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

builder.Services.AddRazorPages();

var app = builder.Build();

注:services.Add{GROUP_NAME} 拡張メソッドは、サービスを追加、場合によっては構成します。 たとえば、AddControllersWithViews ではビューを持つ MVC コントローラーで必要なサービスが追加され、AddRazorPages では Razor Pages で必要なサービスが追加されます。 アプリは、Microsoft.Extensions.DependencyInjection 名前空間で拡張メソッドを作成する場合の名前付け規則に従うようにすることをお勧めします。 Microsoft.Extensions.DependencyInjection 名前空間での拡張メソッドの作成:

  • サービス登録のグループをカプセル化します。
  • サービスへの便利な IntelliSense アクセスを提供します。

セキュリティとユーザー シークレット

構成データのガイドライン:

  • 構成プロバイダーのコードやプレーンテキストの構成ファイルには、パスワードなどの機密データを格納しないでください。 Secret Manager ツールを使用すると、開発時にシークレットを格納できます。
  • 開発環境やテスト環境では運用シークレットを使用しないでください。
  • プロジェクトの外部にシークレットを指定してください。そうすれば、誤ってリソース コード リポジトリにコミットされることはありません。

既定では、ユーザー シークレットの構成ソースは、JSON 構成ソースの後に登録されます。 このため、ユーザー シークレット キーは、 appsettings.json および appsettings. Environment .json よりも優先されます。

パスワードその他の機密データの格納については、次を参照してください:

Azure Key Vault では、ASP.NET Core アプリのアプリのシークレットが安全に保存されます。 詳細については、「ASP.NET Core の Azure Key Vault 構成プロバイダー」を参照してください。

環境変数

既定の構成を使用すると、EnvironmentVariablesConfigurationProvider によって、 appsettings.jsonappsettings. Environment .json、および ユーザー シークレットの読み取り後に、環境変数のキーと値のペアから構成が読み込まれます。 そのため、環境から読み取られたキー値によって、 appsettings.jsonappsettings. Environment .json、およびユーザー シークレットから読み取られた値がオーバーライドされます。

: の区切り記号は、すべてのプラットフォームの環境変数階層キーには対応していません。 __(ダブルアンダースコア)は、

  • すべてのプラットフォームに対応しています。 たとえば、Bash: の区切り記号には対応していませんが、__ には対応しています。
  • 自動で : に置換されます。

次の set コマンドは:

  • Windows で 上記の例 の環境キーと値を設定します。
  • サンプル ダウンロードを使用する際に、設定をテストします。 dotnet run コマンドは、プロジェクト ディレクトリで実行する必要があります。
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

上記の環境設定は:

  • コマンド ウィンドウから起動されたプロセスでのみ設定可能です。
  • Visual Studio で起動されたブラウザーでは読み取れません。

次の setx コマンドで、Windows 上の環境キーと値を設定できます。 set とは異なり、setx 設定は保持されます。 /M は、システム環境で変数を設定します。 /M スイッチが使用されていない場合には、ユーザー環境変数が設定されます。

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

上記のコマンドによって、 appsettings.json および appsettings. Environment .json がオーバーライドされるのをテストするには:

  • Visual Studio の場合:Visual Studio を終了して再起動します。
  • CLI の場合:新しいコマンド ウィンドウを起動し、dotnet run を入力します。

環境変数のプレフィックスを指定する文字列を指定して AddEnvironmentVariables を呼び出します:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

var app = builder.Build();

上のコードでは以下の操作が行われます。

  • config.AddEnvironmentVariables(prefix: "MyCustomPrefix_")既定の構成プロバイダーの後に追加されます。 構成プロバイダーの順序付けの例については、「JSON 構成プロバイダー」を参照してください。
  • MyCustomPrefix_ プレフィックスを使用して設定された環境変数は、既定の構成プロバイダーをオーバーライドします。 これには、プレフィックスのない環境変数が含まれます。

構成のキーと値のペアの読み取り時に、プレフィックスは削除されます。

次のコマンドは、カスタム プレフィックスをテストします:

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

既定の構成では、DOTNET_ASPNETCORE_ のプレフィックスが付いた環境変数とコマンド ライン引数を読み込みます。 DOTNET_ASPNETCORE_ のプレフィックスは ASP.NET Core によってホストとアプリの構成に使用されますが、ユーザーの構成には使用されません。 ホストとアプリの構成の詳細については、「.NET 汎用ホスト」を参照してください。

Azure App Service で、 設定 > 構成 ページの 新しいアプリケーション設定 を選択します。 Azure App Service アプリケーションの設定は:

  • 保存時に暗号化され、暗号化されたチャネルで送信されます。
  • 環境変数として公開されます。

詳細については、「Azure アプリ: Azure Portal を使用してアプリの構成をオーバーライドする」を参照してください。

Azure データベース接続文字列の詳細については、「接続文字列のプレフィックス」を参照してください。

環境変数の名前付け

環境変数名には、 appsettings.json ファイルの構造が反映されます。 階層内の各要素は、二重アンダースコア (推奨) またはコロンによって区切られます。 要素構造に配列が含まれている場合は、配列のインデックスをこのパスの追加の要素名として扱う必要があります。 次の appsettings.json ファイルと、環境変数として表されたその同等の値を考えてみましょう。

appsettings.json

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

環境変数

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

生成された launchSettings.json に設定されている環境変数

launchSettings.json に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。 たとえば、ASP.NET Core Web テンプレートでは、エンドポイント構成を次のように設定する launchSettings.json ファイルが生成されます。

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

applicationUrl を構成すると ASPNETCORE_URLS 環境変数が設定され、環境で設定されている値がオーバーライドされます。

Linux で環境変数をエスケープする

Linux では、systemd で解析できるように URL 環境変数の値をエスケープする必要があります。 Linux ツール systemd-escape を使用すると、http:--localhost:5001 が生成されます

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

環境変数を表示する

次のコードでは、アプリケーションの起動時に環境変数と値が表示されます。これは環境設定をデバッグするときに役立つことがあります。

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

var config = app.Services.GetRequiredService<IConfiguration>();

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

コマンド ライン

既定の構成を使用して、CommandLineConfigurationProvider は、以下の構成ソースの後にコマンド ライン引数のキーと値のペアから構成を読み込みます:

既定では、コマンド ラインで設定された構成値は、他のすべての構成プロバイダーで設定された構成値をオーバーライドします。

コマンド ライン引数

次のコマンドは = を使用してキーと値を設定します:

dotnet run MyKey="My key from command line" Position:Title=Cmd Position:Name=Cmd_Rick

次のコマンドは / を使用してキーと値を設定します:

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

次のコマンドは -- を使用してキーと値を設定します:

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

キーの値:

  • = の後に続ける必要があります。または、値がスペースの後にある場合は、キーのプレフィックスが -- または / である必要があります。
  • = を使用する場合は必要ありません。 たとえば、MySetting= のようにします。

同じコマンド内では、= を使用するコマンド ライン引数のキーと値のペアを、スペースを使用するキーと値のペアと混在させないでください。

スイッチ マッピング

スイッチ マッピングでは、キー 名の置換ロジックが許可されます。 AddCommandLine メソッドにスイッチ置換するディクショナリを提供します。

スイッチ マッピング ディクショナリが使用されている場合、そのディレクトリで、コマンドライン引数によって指定されたキーと一致するキーが確認されます。 ディクショナリ中にコマンド ライン キーが見つかった場合は、そのディクショナリの値が返され、キーと値のペアがアプリの構成に設定されます。 スイッチ マッピングは、単一のダッシュ (-) が前に付いたすべてのコマンドライン キーに必要です。

スイッチ マッピング ディクショナリ キーの規則:

  • スイッチは - または --で始める必要があります。
  • スイッチ マッピング ディクショナリに重複キーを含めることはできません。

スイッチ マッピング ディクショナリを使用するには、それを 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();

次のコマンドを実行して、キーの置換をテストします:

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

次のコードは、置換されたキーのキー値を示しています:

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"]}'");
    }
}

スイッチ マッピングを使用するアプリでは、CreateDefaultBuilder への呼び出しで引数を渡すことはできません。 CreateDefaultBuilder メソッドの AddCommandLine 呼び出しには、マップされたスイッチが含まれていないため、スイッチ マッピング ディクショナリを CreateDefaultBuilder に渡すことはできません。 解決策は、CreateDefaultBuilder に引数を渡す代わりに、ConfigurationBuilder メソッドの AddCommandLine メソッドに、引数とスイッチ マッピング ディクショナリの両方を処理させることです。

Visual Studio で環境とコマンド ライン引数を設定する

環境およびコマンド ラインの引数は、Visual Studio の起動プロファイル ダイアログから設定できます。

  • ソリューション エクスプローラーで、プロジェクトを右クリックして [プロパティ] を選択します。
  • [デバッグ] > [全般] タブの順に選択し、 [Open debug launch profiles UI](デバッグ起動プロファイル UI を開く) を選択します。

階層的な構成データ

構成 API では、構成キーの区切り記号を使用して階層データをフラット化することにより、階層型の構成データの読み取りが行われます。

サンプル ダウンロード には、次の appsettings.json ファイルが含まれます:

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

サンプル ダウンロード の次のコードでは、構成設定のいくつかが表示されます:

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

階層型の構成データを読み取る方法としては、オプション パターンを使用することをお勧めします。 詳細については、このドキュメント中の「階層型の構成データをバインドする」を参照してください。

GetSection メソッドと GetChildren メソッドを使用して、構成データ内のセクションとセクションの子を分離することができます。 これらのメソッドについては、後ほど「GetSection、GetChildren、Exists」で説明します。

構成キーと値

構成キー:

  • 構成キーでは、大文字と小文字は区別されません。 たとえば、ConnectionStringconnectionstring は同等のキーとして扱われます。
  • キーと値が複数の構成プロバイダーで設定されている場合は、最後に追加されたプロバイダーの値が使用されます。 詳細については、「既定の構成」を参照してください。
  • 階層キー
    • 構成 API 内では、すべてのプラットフォームでコロン (:) の区切りが機能します。
    • 環境変数内では、コロン区切りがすべてのプラットフォームでは機能しない場合があります。 ダブル アンダースコア (__) はすべてのプラットフォームでサポートされ、コロン : に自動で変換されます。
    • Azure Key Vault では、階層型のキーは区切り記号に -- を使用します。 シークレットがアプリの構成に読み込まれると、Azure Key Vault 構成プロバイダーによって --: に自動的に置き換えられます。
  • ConfigurationBinder は、構成キーで配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 配列のバインドについては、「配列をクラスにバインドする」セクションで説明します。

構成値:

  • 構成値は文字列です。
  • Null 値を構成に格納したり、オブジェクトにバインドしたりすることはできません。

構成プロバイダー

ASP.NET Core アプリで使用できる構成プロバイダーを次の表に示します。

プロバイダー 以下から構成を提供します
Azure Key Vault 構成プロバイダー Azure Key Vault
Azure App Configuration プロバイダー Azure App Configuration
コマンド ライン構成プロバイダー コマンド ライン パラメーター
カスタム構成プロバイダー カスタム ソース
環境変数構成プロバイダー 環境変数
ファイル構成プロバイダー INI、JSON、および XML ファイル
ファイルごとのキーの構成プロバイダー ディレクトリ ファイル
メモリ構成プロバイダー メモリ内コレクション
ユーザー シークレット ユーザー プロファイル ディレクトリ内のファイル

構成ソースは、構成プロバイダーで指定された順序で読み取られます。 アプリで必要とされる、基になる構成ソースの優先順位に合わせるために、コード内で構成プロバイダーを並べ替えます。

一般的な一連の構成プロバイダーは次のとおりです。

  1. appsettings.json
  2. appsettings.Environment.json
  3. ユーザー シークレット
  4. 環境変数構成プロバイダーを使用する環境変数。
  5. コマンドライン構成プロバイダーを使用するコマンドライン引数。

コマンド ライン引数が他のプロバイダーによって設定された構成をオーバーライドできるようにするには、コマンド ラインの構成プロバイダーを一連のプロバイダーの最後に配置するのが一般的です。

上記の一連のプロバイダーは、既定の構成で使用されます。

接続文字列のプレフィックス

構成 API には、4つの接続文字列環境変数に対する特別なプロセスルールがあります。 これらの接続文字列は、アプリ環境用の Azure 接続文字列の構成に含まれています。 表に示されたプレフィックスを持つ環境変数は、既定の構成 を使用するとき、または AddEnvironmentVariables にプレフィックスが指定されていない場合に、アプリに読み込まれます。

接続文字列のプレフィックス プロバイダー
CUSTOMCONNSTR_ カスタム プロバイダー
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

表に示す 4 つのプレフィックスのいずれかを使用して、環境変数が検出され構成に読み込まれた場合:

  • 環境変数のプレフィックスを削除し、構成キーのセクション (ConnectionStrings) を追加することによって、構成キーが作成されます。
  • データベースの接続プロバイダーを表す新しい構成のキーと値のペアが作成されます (示されたプロバイダーを含まない CUSTOMCONNSTR_ を除く)。
環境変数キー 変換された構成キー プロバイダーの構成エントリ
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 構成エントリは作成されません。
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: System.Data.SqlClient

ファイル構成プロバイダー

FileConfigurationProvider は、ファイル システムから構成を読み込むための基本クラスです。 以下の構成プロバイダーは FileConfigurationProvider から派生したものです:

INI 構成プロバイダー

IniConfigurationProvider では、実行時に INI ファイルのキーと値のペアから構成が読み込まれます。

次のコードでは、すべての構成プロバイダーをクリアし、いくつかの構成プロバイダーを追加します: [!code-csharp]

上記のコードでは、MyIniConfig.iniMyIniConfig.Environment.ini ファイルの設定は、以下の設定によってオーバーライドされます:

サンプルダウンロード には、次の MyIniConfig ファイルが含まれます:

MyKey="MyIniConfig.ini Value"

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

[Logging:LogLevel]
Default=Information
Microsoft=Warning

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

JSON 構成プロバイダー

JsonConfigurationProvider では、JSON ファイルのキーと値のペアから構成が読み込みまれます。

オーバーロードでは、次の指定ができます:

  • ファイルを省略可能かどうか。
  • ファイルが変更された場合に構成を再度読み込むかどうか。

次のコードがあるとします。

using Microsoft.Extensions.DependencyInjection.ConfigSample.Options;

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MyConfig.json",
                       optional: true,
                       reloadOnChange: true);
});

builder.Services.AddRazorPages();

var app = builder.Build();

上記のコードでは次の操作が行われます。

  • 次のオプションを使用して、MyConfig.json ファイルを読み込むように JSON 構成プロバイダーを構成します:
    • optional: true:ファイルは省略可能です。
    • reloadOnChange: true は、次のとおりです。変更が保存されると、ファイルが再読み込みされます。
  • MyConfig.json ファイルの前に 既定の構成プロバイダーを読み取ります。 環境変数構成プロバイダー および コマンド ライン構成プロバイダーを含む、既定の構成プロバイダーでの MyConfig.json ファイルのオーバーライドの設定。

通常は、環境変数構成プロバイダーおよび コマンドライン構成プロバイダーで設定されている値をオーバーライドするカスタム JSON ファイルは 必要ありません

XML 構成プロバイダー

XmlConfigurationProvider では、実行時に XML ファイルのキーと値のペアから構成が読み込まれます。

次のコードは、すべての構成プロバイダーをクリアし、いくつかの構成プロバイダーを追加します:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    var env = hostingContext.HostingEnvironment;

    config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
          .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                         optional: true, reloadOnChange: true);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

上記のコードでは、MyXMLFile.xmlMyXMLFile.Environment.xml ファイルの設定は、以下の設定によってオーバーライドされます:

サンプルダウンロード には、次の 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>

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

同じ要素名を使用する要素の繰り返しは、要素を区別するために 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>

以下のコードでは、前の構成ファイルを読み取って、キーと値を表示します:

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

値を指定するために属性を使用できます。

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

前の構成ファイルでは、value を使用して次のキーが読み込まれます。

  • key:attribute
  • section:key:attribute

ファイルごとのキーの構成プロバイダー

KeyPerFileConfigurationProvider では、構成のキーと値のペアとしてディレクトリのファイルが使用されます。 キーはファイル名です。 値にはファイルのコンテンツが含まれます。 ファイルごとのキーの構成プロバイダーは、Docker ホスティングのシナリオで使用されます。

ファイルごとのキーの構成をアクティブにするには、ConfigurationBuilder のインスタンスの AddKeyPerFile 拡張メソッドを呼び出します。 ファイルに対する directoryPath は、絶対パスである必要があります。

オーバーロードによって次のものを指定できます。

  • ソースを構成する Action<KeyPerFileConfigurationSource> デリゲート。
  • ディレクトリを省略可能かどうか、またディレクトリへのパス。

アンダースコア 2 つ (__) は、ファイル名で構成キーの区切り記号として使用されます。 たとえば、ファイル名 Logging__LogLevel__System では、構成キー Logging:LogLevel:System が生成されます。

ホストをビルドするときに ConfigureAppConfiguration を呼び出して、アプリの構成を指定します。

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

メモリ構成プロバイダー

MemoryConfigurationProvider では、構成のキーと値のペアとして、メモリ内コレクションが使用されます。

次のコードでは、構成システムにメモリコ レクションが追加されています:

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.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    config.AddInMemoryCollection(Dict);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

サンプルのダウンロード の以下のコードでは、上記の構成設定のいくつかが表示されます:

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

上記のコードでは、既定の構成プロバイダーの後に config.AddInMemoryCollection(Dict) が追加されています。 構成プロバイダーの順序付けの例については、「JSON 構成プロバイダー」を参照してください。

MemoryConfigurationProvider を使用した別の例については、配列をバインドを参照してください。

Kestrel エンドポイント構成

Kestrel 固有のエンドポイント構成によって、すべてのサーバー間のエンドポイント構成がオーバーライドされます。 サーバー間のエンドポイント構成には、次のものがあります。

ASP.NET Core Web アプリで使用される次の appsettings.json ファイルについて考えてみましょう。

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

上の強調表示されているマークアップが ASP.NET Core Web アプリで使用され、"かつ" 次のサーバー間エンドポイント構成を使用してコマンド ラインでアプリが起動される場合:

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

Kestrel は、https://localhost:7777 ではなく、 appsettings.json ファイルで Kestrel 専用に構成されたエンドポイント (https://localhost:9999) にバインドされます。

環境変数として構成された Kestrel 固有のエンドポイントを考えてみます。

set Kestrel__Endpoints__Https__Url=https://localhost:8888

上記の環境変数では、Https が Kestrel 固有のエンドポイントの名前です。 前の appsettings.json ファイルでも、Https という名前の Kestrel 固有のエンドポイントが定義されています。 既定で、環境変数構成プロバイダーを使用している環境変数は appsettings. Environment .json の後に読み取られます。したがって、上記の環境変数は Https エンドポイント用に使用されます。

GetValue

ConfigurationBinder.GetValue<T> 指定したキーを使用して、構成から単一の値を抽出し、それを指定した型に変換します:

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

上記のコードでは、NumberKey が構成中に見つからない場合には 99 の既定値が使用されます。

GetSection、GetChildren、Exists

以下の例では、次の MySubsection.json ファイルについて考えます:

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

以下のコードでは、MySubsection セクション を構成プロバイダーに追加します:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MySubsection.json",
                       optional: true,
                       reloadOnChange: true);
});

builder.Services.AddRazorPages();

var app = builder.Build();

GetSection

IConfiguration.GetSection は、指定されたサブセクションのキーを持つ構成サブセクションを返します。

次のコードは、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"]}'");
    }
}

次のコードは、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"]}'");
    }
}

GetSectionnull を返すことはありません。 一致するセクションが見つからない場合は、空の IConfigurationSection が返されます。

GetSection で一致するセクションが返されると、Value は設定されません。 KeyPath はセクションが存在する場合に返されます。

GetChildren と Exists

次のコードは、IConfiguration.GetChildren を呼び出し、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);
    }
}

上記のコードは、ConfigurationExtensions. Exists を呼び出し、セクションが存在することを確認します:

配列をバインドする

ConfigurationBinder. Bind は、構成キーの配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 数値のキー セグメントを公開する配列形式は、すべて POCO クラスの配列にバインドできます。

サンプル ダウンロードMyArray.json について考えます:

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

次のコードでは、MyArray.json を構成プロバイダーに追加します:

var builder = WebApplication.CreateBuilder(args);

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile("MyArray.json",
                        optional: true,
                        reloadOnChange: true); ;
});

builder.Services.AddRazorPages();

var app = builder.Build();

次のコードでは、構成を読み取り、値を表示します:

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

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

    public ContentResult OnGet()
    {
        if (_array == null)
        {
            throw new ArgumentNullException(nameof(_array));
        }

        _array = Config.GetSection("array").Get<ArrayExample>();
        string s = String.Empty;

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

        return Content(s);
    }
}

上記のコードは、次の出力を返します:

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

上記の出力では、インデックス3の値が value40 になります。これは MyArray. json"4": "value40", に対応しています。 このバインドされた配列インデックスは連続的であり、構成キーインデックスにバインドされていません。 構成バインダーは、バインドされたオブジェクトに null 値をバインドしたり、null エントリを作成したりはできません

Razor ページの構成にアクセスする

次のコードでは Razor ページの構成データが表示されます:

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

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

次のコードでは、MyOptionsConfigure でサービスコンテナーに追加され、構成にバインドされます:

using SampleApp.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

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

var app = builder.Build();

次のマークアップは、@inject Razor ディレクティブを使用して、オプションの値を解決して表示します。

@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>

MVC ビューファイルの構成へのアクセス

次のコードでは、MVC ビューの構成データが表示されます:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

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

デリゲートでオプションを構成する

デリゲートで構成されたオプションは、構成プロバイダーで設定された値をオーバーライドします。

次のコードでは、IConfigureOptions<TOptions> サービスがサービス コンテナーに追加されます。 デリゲートを利用して 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();

このコードには、次のオプションの値が表示されます。

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

先の例では、値 Option1Option2appsettings.json で指定されてから、構成されているデリゲートによりオーバーライドされます。

ホストとアプリの構成

アプリを構成して起動する前に、"ホスト" を構成して起動します。 ホストはアプリの起動と有効期間の管理を担当します。 アプリとホストは、両方ともこのトピックで説明する構成プロバイダーを使用して構成します。 ホスト構成のキーと値のペアも、アプリの構成に含まれます。 ホストをビルドするときの構成プロバイダーの使用方法、およびホストの構成に対する構成ソースの影響について詳しくは、「ASP.NET Core の基礎」をご覧ください。

既定のホスト構成

Web ホストを使用する場合の既定の構成の詳細については、このトピックの ASP.NET Core 2.2 バージョンを参照してください。

  • ホストの構成は、次から提供されます。
  • Web ホストの既定の構成が確立されます (ConfigureWebHostDefaults)。
    • Kestrel は Web サーバーとして使用され、アプリの構成プロバイダーを使用して構成されます。
    • Host Filtering Middleware を追加します。
    • ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境変数が true に設定されている場合は、Forwarded Headers Middleware を追加します。
    • IIS 統合を有効にします。

その他の構成

このトピックは、"アプリの構成" のみに関連しています。 ASP.NET Core アプリの実行とホストに関するその他の側面は、このトピックでは扱わない構成ファイルを使って構成されます。

launchSettings.json に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。

以前のバージョンの ASP.NET からアプリの構成を移行する方法について詳しくは、ASP.NET から ASP.NET Core への移行 をご覧ください。

外部アセンブリから構成を追加する

IHostingStartup の実装により、アプリの Startup クラスの外部にある外部アセンブリから、起動時に拡張機能をアプリに追加できるようになります。 詳細については、「ASP.NET Core でホスティング スタートアップ アセンブリを使用する」を参照してください。

その他の技術情報

ASP.NET Core の構成は、1つまたは複数の構成プロバイダーを使用して実行されます。 構成プロバイダーは、以下のようなさまざまな構成ソースを使用して、キーと値のペアから構成データを読み取ります:

  • appsettings.json などの設定ファイル
  • 環境変数
  • Azure Key Vault
  • Azure App Configuration
  • コマンド ライン引数
  • インストール済みまたは作成済みのカスタム プロバイダー
  • ディレクトリ ファイル
  • メモリ内 .NET オブジェクト

このトピックでは ASP.NET Core の構成について説明します。 コンソール アプリでの構成の使用方法について詳しくは、.NET 構成に関する記事をご覧ください。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

既定の構成

dotnet new または Visual Studio で作成された ASP.NET Core の web アプリが、次のコードを生成します:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

CreateDefaultBuilder により、次の順序でアプリの既定の構成が提供されます。

  1. ChainedConfigurationProvider は:既存の IConfiguration をソースとして追加します。 既定の構成では、ホスト構成を追加し、アプリ 構成の最初のソースとして設定します。
  2. JSON 構成プロバイダーを使用する appsettings.json
  3. JSON 構成プロバイダーを使用する appsettings. Environmentjson。 たとえば、appsettings.Production_._json および appsettings.Development _._json
  4. Development 環境でアプリが実行される際の App シークレット
  5. 環境変数構成プロバイダーを使用する環境変数。
  6. コマンドライン構成プロバイダーを使用するコマンドライン引数。

後から追加される構成プロバイダーは、それ以前のキー設定をオーバーライドします。 たとえば、MyKeyappsettings.json と環境の両方で設定されている場合、環境の値が使用されます。 既定の構成プロバイダーを使用すると、コマンドライン構成プロバイダー が他のすべてのプロバイダーをオーバーライドします。

CreateDefaultBuilder の詳細については、既定のビルダー設定を参照してください。

以下のコードでは、追加した順に、有効な構成プロバイダーが表示されます:

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

appsettings.json

次の appsettings.json ファイルを考えてみます。

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

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

既定の JsonConfigurationProvider は、以下の順序で構成を読み込みます:

  1. appsettings.json
  2. appsettings. Environment .json:たとえば、appsettings.Production_._json および appsettings.Development _._json ファイル。 ファイルの環境バージョンは、IHostingEnvironment.EnvironmentNameに基づいて読み込まれます。 詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。

appsettings.Environment.json の値によって、 appsettings.json 内のキーがオーバーライドされます。 たとえば、既定では次のようになります:

  • 開発中は、appsettings.Development _._json 構成によって、 appsettings.json で見つかった値が上書きされます。
  • 運用環境では、appsettings.Production _._json 構成によって、 appsettings.json で見つかった値が上書きされます。 たとえば、Azure にアプリをデプロイする場合。

構成値を保証する必要がある場合は、「GetValue」を参照してください。 前の例では文字列が読み取られるだけで、既定値はサポートされていません。

既定の構成を利用する場合、reloadOnChange: trueappsettings.jsonappsettings. Environment .json ファイルを有効にすることができます。 アプリの開始 appsettings.jsonappsettings. Environment .json ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。

オプションパターンを使用して、階層型の構成データをバインドします

関連する構成値を読み取る方法としては、オプション パターンを使用することをお勧めします。 たとえば、以下の構成値を読み取るには、次のようにします:

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

次の PositionOptions クラスを作成します:

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

    public string Title { get; set; }
    public string Name { get; set; }
}

オプション クラス:

  • パラメーターのないパブリック コンストラクターを持った非抽象でなければなりません。
  • 型のパブリックな読み取り/書き込みプロパティは、すべてバインドされます。
  • フィールドはバインド されません。 上のコード Position はバインドされません。 Position プロパティは、クラスを構成プロバイダーにバインドするときに、アプリで文字列 "Position" をハードコーディングする必要をなくすために使用されます。

コード例を次に示します。

  • ConfigurationBinder.Bind を呼び出して、PositionOptions クラスを Position セクションにバインドします。
  • 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}");
    }
}

上のコードでは、アプリが開始された後の JSON 構成ファイルへの変更が既定で読み取られます。

ConfigurationBinder.Get<T> 指定された型をバインドして返します。 ConfigurationBinder.Get<T>ConfigurationBinder.Bind を使用するよりも便利な場合があります。 次のコードは、PositionOptions クラスで ConfigurationBinder.Get<T> を使用する方法を示しています:

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

上のコードでは、アプリが開始された後の JSON 構成ファイルへの変更が既定で読み取られます。

*オプション パターン _ を使用する際の別の方法として、Position セクションをバインドし、依存関係挿入サービスコンテナーに追加する方法があります。 次のコードでは、PositionOptions は <xref:Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure_> でサービスコンテナーに追加され、構成にバインドされます:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(Configuration.GetSection(
                                        PositionOptions.Position));
    services.AddRazorPages();
}

下記のコードは、上記のコードを使用して位置オプションを読み取ります:

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

上のコードでは、アプリが開始された後の JSON 構成ファイルへの変更は読み取られ ません。 アプリの開始後に変更を読み取るには、IOptionsSnapshot を使用します。

既定の構成を利用する場合、reloadOnChange: trueappsettings.jsonappsettings. Environment .json ファイルを有効にすることができます。 アプリの開始 appsettings.jsonappsettings. Environment .json ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。

追加の JSON 構成ファイルを追加する方法の詳細については、このドキュメント中の「JSON 構成プロバイダー」を参照してください。

サービス コレクションの結合

サービスを登録し、オプションを構成する次の ConfigureServices メソッドについて考えてみましょう。

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<PositionOptions>(
        Configuration.GetSection(PositionOptions.Position));
    services.Configure<ColorOptions>(
        Configuration.GetSection(ColorOptions.Color));

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

    services.AddRazorPages();
}

関連する登録グループは、サービスを登録するための拡張メソッドに移動できます。 たとえば、構成サービスは次のクラスに追加されます。

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

残りのサービスは、同様のクラスに登録されます。 次の ConfigureServices メソッドでは、新しい拡張メソッドを使用してサービスを登録します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddConfig(Configuration)
            .AddMyDependencyGroup();

    services.AddRazorPages();
}

注:services.Add{GROUP_NAME} 拡張メソッドは、サービスを追加、場合によっては構成します。 たとえば、AddControllersWithViews ではビューを持つ MVC コントローラーで必要なサービスが追加され、AddRazorPages では Razor Pages で必要なサービスが追加されます。 アプリは、Microsoft.Extensions.DependencyInjection 名前空間で拡張メソッドを作成する場合の名前付け規則に従うようにすることをお勧めします。 Microsoft.Extensions.DependencyInjection 名前空間での拡張メソッドの作成:

  • サービス登録のグループをカプセル化します。
  • サービスへの便利な IntelliSense アクセスを提供します。

セキュリティとユーザー シークレット

構成データのガイドライン:

  • 構成プロバイダーのコードやプレーンテキストの構成ファイルには、パスワードなどの機密データを格納しないでください。 Secret Manager ツールを使用すると、開発時にシークレットを格納できます。
  • 開発環境やテスト環境では運用シークレットを使用しないでください。
  • プロジェクトの外部にシークレットを指定してください。そうすれば、誤ってリソース コード リポジトリにコミットされることはありません。

既定では、ユーザー シークレットの構成ソースは、JSON 構成ソースの後に登録されます。 このため、ユーザー シークレット キーは、 appsettings.json および appsettings. Environment .json よりも優先されます。

パスワードその他の機密データの格納については、次を参照してください:

Azure Key Vault では、ASP.NET Core アプリのアプリのシークレットが安全に保存されます。 詳細については、「ASP.NET Core の Azure Key Vault 構成プロバイダー」を参照してください。

環境変数

既定の構成を使用すると、EnvironmentVariablesConfigurationProvider によって、 appsettings.jsonappsettings. Environment .json、および ユーザー シークレットの読み取り後に、環境変数のキーと値のペアから構成が読み込まれます。 そのため、環境から読み取られたキー値によって、 appsettings.jsonappsettings. Environment .json、およびユーザー シークレットから読み取られた値がオーバーライドされます。

: の区切り記号は、すべてのプラットフォームの環境変数階層キーには対応していません。 __(ダブルアンダースコア)は、

  • すべてのプラットフォームに対応しています。 たとえば、Bash: の区切り記号には対応していませんが、__ には対応しています。
  • 自動で : に置換されます。

次の set コマンドは:

  • Windows で 上記の例 の環境キーと値を設定します。
  • サンプル ダウンロードを使用する際に、設定をテストします。 dotnet run コマンドは、プロジェクト ディレクトリで実行する必要があります。
set MyKey="My key from Environment"
set Position__Title=Environment_Editor
set Position__Name=Environment_Rick
dotnet run

上記の環境設定は:

  • コマンド ウィンドウから起動されたプロセスでのみ設定可能です。
  • Visual Studio で起動されたブラウザーでは読み取れません。

次の setx コマンドで、Windows 上の環境キーと値を設定できます。 set とは異なり、setx 設定は保持されます。 /M は、システム環境で変数を設定します。 /M スイッチが使用されていない場合には、ユーザー環境変数が設定されます。

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

上記のコマンドによって、 appsettings.json および appsettings. Environment .json がオーバーライドされるのをテストするには:

  • Visual Studio の場合:Visual Studio を終了して再起動します。
  • CLI の場合:新しいコマンド ウィンドウを起動し、dotnet run を入力します。

環境変数のプレフィックスを指定する文字列を指定して AddEnvironmentVariables を呼び出します:

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.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上のコードでは以下の操作が行われます。

  • config.AddEnvironmentVariables(prefix: "MyCustomPrefix_")既定の構成プロバイダーの後に追加されます。 構成プロバイダーの順序付けの例については、「JSON 構成プロバイダー」を参照してください。
  • MyCustomPrefix_ プレフィックスを使用して設定された環境変数は、既定の構成プロバイダーをオーバーライドします。 これには、プレフィックスのない環境変数が含まれます。

構成のキーと値のペアの読み取り時に、プレフィックスは削除されます。

次のコマンドは、カスタム プレフィックスをテストします:

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

既定の構成では、DOTNET_ASPNETCORE_ のプレフィックスが付いた環境変数とコマンド ライン引数を読み込みます。 DOTNET_ASPNETCORE_ のプレフィックスは ASP.NET Core によってホストとアプリの構成に使用されますが、ユーザーの構成には使用されません。 ホストとアプリの構成の詳細については、「.NET 汎用ホスト」を参照してください。

Azure App Service で、 設定 > 構成 ページの 新しいアプリケーション設定 を選択します。 Azure App Service アプリケーションの設定は:

  • 保存時に暗号化され、暗号化されたチャネルで送信されます。
  • 環境変数として公開されます。

詳細については、「Azure アプリ: Azure Portal を使用してアプリの構成をオーバーライドする」を参照してください。

Azure データベース接続文字列の詳細については、「接続文字列のプレフィックス」を参照してください。

環境変数の名前付け

環境変数名には、 appsettings.json ファイルの構造が反映されます。 階層内の各要素は、二重アンダースコア (推奨) またはコロンによって区切られます。 要素構造に配列が含まれている場合は、配列のインデックスをこのパスの追加の要素名として扱う必要があります。 次の appsettings.json ファイルと、環境変数として表されたその同等の値を考えてみましょう。

appsettings.json

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

環境変数

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

生成された launchSettings.json に設定されている環境変数

launchSettings.json に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。 たとえば、ASP.NET Core Web テンプレートでは、エンドポイント構成を次のように設定する launchSettings.json ファイルが生成されます。

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

applicationUrl を構成すると ASPNETCORE_URLS 環境変数が設定され、環境で設定されている値がオーバーライドされます。

Linux で環境変数をエスケープする

Linux では、systemd で解析できるように URL 環境変数の値をエスケープする必要があります。 Linux ツール systemd-escape を使用すると、http:--localhost:5001 が生成されます

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

環境変数を表示する

次のコードでは、アプリケーションの起動時に環境変数と値が表示されます。これは環境設定をデバッグするときに役立つことがあります。

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var config = host.Services.GetRequiredService<IConfiguration>();

    foreach (var c in config.AsEnumerable())
    {
        Console.WriteLine(c.Key + " = " + c.Value);
    }
    host.Run();
}

コマンド ライン

既定の構成を使用して、CommandLineConfigurationProvider は、以下の構成ソースの後にコマンド ライン引数のキーと値のペアから構成を読み込みます:

既定では、コマンド ラインで設定された構成値は、他のすべての構成プロバイダーで設定された構成値をオーバーライドします。

コマンド ライン引数

次のコマンドは = を使用してキーと値を設定します:

dotnet run MyKey="My key from command line" Position:Title=Cmd Position:Name=Cmd_Rick

次のコマンドは / を使用してキーと値を設定します:

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

次のコマンドは -- を使用してキーと値を設定します:

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

キーの値:

  • = の後に続ける必要があります。または、値がスペースの後にある場合は、キーのプレフィックスが -- または / である必要があります。
  • = を使用する場合は必要ありません。 たとえば、MySetting= のようにします。

同じコマンド内では、= を使用するコマンド ライン引数のキーと値のペアを、スペースを使用するキーと値のペアと混在させないでください。

スイッチ マッピング

スイッチ マッピングでは、キー 名の置換ロジックが許可されます。 AddCommandLine メソッドにスイッチ置換するディクショナリを提供します。

スイッチ マッピング ディクショナリが使用されている場合、そのディレクトリで、コマンドライン引数によって指定されたキーと一致するキーが確認されます。 ディクショナリ中にコマンド ライン キーが見つかった場合は、そのディクショナリの値が返され、キーと値のペアがアプリの構成に設定されます。 スイッチ マッピングは、単一のダッシュ (-) が前に付いたすべてのコマンドライン キーに必要です。

スイッチ マッピング ディクショナリ キーの規則:

  • スイッチは - または --で始める必要があります。
  • スイッチ マッピング ディクショナリに重複キーを含めることはできません。

スイッチ マッピング ディクショナリを使用するには、それを AddCommandLine の呼び出しに渡します:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

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

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddCommandLine(args, switchMappings);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

次のコードは、置換されたキーのキー値を示しています:

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"]}'");
    }
}

次のコマンドを実行して、キーの置換をテストできます:

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

スイッチ マッピングを使用するアプリでは、CreateDefaultBuilder への呼び出しで引数を渡すことはできません。 CreateDefaultBuilder メソッドの AddCommandLine 呼び出しには、マップされたスイッチが含まれていないため、スイッチ マッピング ディクショナリを CreateDefaultBuilder に渡すことはできません。 解決策は、CreateDefaultBuilder に引数を渡す代わりに、ConfigurationBuilder メソッドの AddCommandLine メソッドに、引数とスイッチ マッピング ディクショナリの両方を処理させることです。

Visual Studio で環境とコマンド ライン引数を設定する

次の図は、Visual Studio で環境とコマンドライン引数を設定する方法を示しています。

VS の [デバッグ] タブ

Visual Studio 2019 バージョン 16.10 Preview 4 以降では、起動プロファイルの UI から環境とコマンドライン引数を設定します。

起動プロファイルの UI

階層的な構成データ

構成 API では、構成キーの区切り記号を使用して階層データをフラット化することにより、階層型の構成データの読み取りが行われます。

サンプル ダウンロード には、次の appsettings.json ファイルが含まれます:

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

サンプル ダウンロード の次のコードでは、構成設定のいくつかが表示されます:

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

階層型の構成データを読み取る方法としては、オプション パターンを使用することをお勧めします。 詳細については、このドキュメント中の「階層型の構成データをバインドする」を参照してください。

GetSection メソッドと GetChildren メソッドを使用して、構成データ内のセクションとセクションの子を分離することができます。 これらのメソッドについては、後ほど「GetSection、GetChildren、Exists」で説明します。

構成キーと値

構成キー:

  • 構成キーでは、大文字と小文字は区別されません。 たとえば、ConnectionStringconnectionstring は同等のキーとして扱われます。
  • キーと値が複数の構成プロバイダーで設定されている場合は、最後に追加されたプロバイダーの値が使用されます。 詳細については、「既定の構成」を参照してください。
  • 階層キー
    • 構成 API 内では、すべてのプラットフォームでコロン (:) の区切りが機能します。
    • 環境変数内では、コロン区切りがすべてのプラットフォームでは機能しない場合があります。 ダブル アンダースコア (__) はすべてのプラットフォームでサポートされ、コロン : に自動で変換されます。
    • Azure Key Vault では、階層型のキーは区切り記号に -- を使用します。 シークレットがアプリの構成に読み込まれると、Azure Key Vault 構成プロバイダーによって --: に自動的に置き換えられます。
  • ConfigurationBinder は、構成キーで配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 配列のバインドについては、「配列をクラスにバインドする」セクションで説明します。

構成値:

  • 構成値は文字列です。
  • Null 値を構成に格納したり、オブジェクトにバインドしたりすることはできません。

構成プロバイダー

ASP.NET Core アプリで使用できる構成プロバイダーを次の表に示します。

プロバイダー 以下から構成を提供します
Azure Key Vault 構成プロバイダー Azure Key Vault
Azure App Configuration プロバイダー Azure App Configuration
コマンド ライン構成プロバイダー コマンド ライン パラメーター
カスタム構成プロバイダー カスタム ソース
環境変数構成プロバイダー 環境変数
ファイル構成プロバイダー INI、JSON、および XML ファイル
ファイルごとのキーの構成プロバイダー ディレクトリ ファイル
メモリ構成プロバイダー メモリ内コレクション
ユーザー シークレット ユーザー プロファイル ディレクトリ内のファイル

構成ソースは、構成プロバイダーで指定された順序で読み取られます。 アプリで必要とされる、基になる構成ソースの優先順位に合わせるために、コード内で構成プロバイダーを並べ替えます。

一般的な一連の構成プロバイダーは次のとおりです。

  1. appsettings.json
  2. appsettings.Environment.json
  3. ユーザー シークレット
  4. 環境変数構成プロバイダーを使用する環境変数。
  5. コマンドライン構成プロバイダーを使用するコマンドライン引数。

コマンド ライン引数が他のプロバイダーによって設定された構成をオーバーライドできるようにするには、コマンド ラインの構成プロバイダーを一連のプロバイダーの最後に配置するのが一般的です。

上記の一連のプロバイダーは、既定の構成で使用されます。

接続文字列のプレフィックス

構成 API には、4つの接続文字列環境変数に対する特別なプロセスルールがあります。 これらの接続文字列は、アプリ環境用の Azure 接続文字列の構成に含まれています。 表に示されたプレフィックスを持つ環境変数は、既定の構成 を使用するとき、または AddEnvironmentVariables にプレフィックスが指定されていない場合に、アプリに読み込まれます。

接続文字列のプレフィックス プロバイダー
CUSTOMCONNSTR_ カスタム プロバイダー
MYSQLCONNSTR_ MySQL
SQLAZURECONNSTR_ Azure SQL Database
SQLCONNSTR_ SQL Server

表に示す 4 つのプレフィックスのいずれかを使用して、環境変数が検出され構成に読み込まれた場合:

  • 環境変数のプレフィックスを削除し、構成キーのセクション (ConnectionStrings) を追加することによって、構成キーが作成されます。
  • データベースの接続プロバイダーを表す新しい構成のキーと値のペアが作成されます (示されたプロバイダーを含まない CUSTOMCONNSTR_ を除く)。
環境変数キー 変換された構成キー プロバイダーの構成エントリ
CUSTOMCONNSTR_{KEY} ConnectionStrings:{KEY} 構成エントリは作成されません。
MYSQLCONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: MySql.Data.MySqlClient
SQLAZURECONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: System.Data.SqlClient
SQLCONNSTR_{KEY} ConnectionStrings:{KEY} キー: ConnectionStrings:{KEY}_ProviderName:
値: System.Data.SqlClient

ファイル構成プロバイダー

FileConfigurationProvider は、ファイル システムから構成を読み込むための基本クラスです。 以下の構成プロバイダーは FileConfigurationProvider から派生したものです:

INI 構成プロバイダー

IniConfigurationProvider では、実行時に INI ファイルのキーと値のペアから構成が読み込まれます。

次のコードは、すべての構成プロバイダーをクリアし、いくつかの構成プロバイダーを追加します:

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.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddIniFile("MyIniConfig.ini", optional: true, reloadOnChange: true)
                      .AddIniFile($"MyIniConfig.{env.EnvironmentName}.ini",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上記のコードでは、MyIniConfig.iniMyIniConfig.Environment.ini ファイルの設定は、以下の設定によってオーバーライドされます:

サンプルダウンロード には、次の MyIniConfig ファイルが含まれます:

MyKey="MyIniConfig.ini Value"

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

[Logging:LogLevel]
Default=Information
Microsoft=Warning

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

JSON 構成プロバイダー

JsonConfigurationProvider では、JSON ファイルのキーと値のペアから構成が読み込みまれます。

オーバーロードでは、次の指定ができます:

  • ファイルを省略可能かどうか。
  • ファイルが変更された場合に構成を再度読み込むかどうか。

次のコードがあるとします。

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("MyConfig.json", 
                    optional: true, 
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上記のコードでは次の操作が行われます。

  • 次のオプションを使用して、MyConfig.json ファイルを読み込むように JSON 構成プロバイダーを構成します:
    • optional: true:ファイルは省略可能です。
    • reloadOnChange: true は、次のとおりです。変更が保存されると、ファイルが再読み込みされます。
  • MyConfig.json ファイルの前に 既定の構成プロバイダーを読み取ります。 環境変数構成プロバイダー および コマンド ライン構成プロバイダーを含む、既定の構成プロバイダーでの MyConfig.json ファイルのオーバーライドの設定。

通常は、環境変数構成プロバイダーおよび コマンドライン構成プロバイダーで設定されている値をオーバーライドするカスタム JSON ファイルは 必要ありません

次のコードは、すべての構成プロバイダーをクリアし、いくつかの構成プロバイダーを追加します:

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.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
                                     optional: true, reloadOnChange: true);

                config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true)
                      .AddJsonFile($"MyConfig.{env.EnvironmentName}.json",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上記のコードでは、MyConfig.jsonMyConfig.Environment.json ファイルの設定は:

サンプル ダウンロードには、次の MyConfig.json ファイルが含まれます:

{
    "Position": {
        "Title": "構成のタイトル",
        "Name": "My Config Smith"
    },
    "MyKey": "MyConfig.json Value",
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*"
}

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

XML 構成プロバイダー

XmlConfigurationProvider では、実行時に XML ファイルのキーと値のペアから構成が読み込まれます。

次のコードは、すべての構成プロバイダーをクリアし、いくつかの構成プロバイダーを追加します:

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.Sources.Clear();

                var env = hostingContext.HostingEnvironment;

                config.AddXmlFile("MyXMLFile.xml", optional: true, reloadOnChange: true)
                      .AddXmlFile($"MyXMLFile.{env.EnvironmentName}.xml",
                                     optional: true, reloadOnChange: true);

                config.AddEnvironmentVariables();

                if (args != null)
                {
                    config.AddCommandLine(args);
                }
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

上記のコードでは、MyXMLFile.xmlMyXMLFile.Environment.xml ファイルの設定は、以下の設定によってオーバーライドされます:

サンプルダウンロード には、次の 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>

サンプル ダウンロード の次のコードでは、上記の構成設定のいくつかが表示されます:

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

同じ要素名を使用する要素の繰り返しは、要素を区別するために 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>

以下のコードでは、前の構成ファイルを読み取って、キーと値を表示します:

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

値を指定するために属性を使用できます。

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

前の構成ファイルでは、value を使用して次のキーが読み込まれます。

  • key:attribute
  • section:key:attribute

ファイルごとのキーの構成プロバイダー

KeyPerFileConfigurationProvider では、構成のキーと値のペアとしてディレクトリのファイルが使用されます。 キーはファイル名です。 値にはファイルのコンテンツが含まれます。 ファイルごとのキーの構成プロバイダーは、Docker ホスティングのシナリオで使用されます。

ファイルごとのキーの構成をアクティブにするには、ConfigurationBuilder のインスタンスの AddKeyPerFile 拡張メソッドを呼び出します。 ファイルに対する directoryPath は、絶対パスである必要があります。

オーバーロードによって次のものを指定できます。

  • ソースを構成する Action<KeyPerFileConfigurationSource> デリゲート。
  • ディレクトリを省略可能かどうか、またディレクトリへのパス。

アンダースコア 2 つ (__) は、ファイル名で構成キーの区切り記号として使用されます。 たとえば、ファイル名 Logging__LogLevel__System では、構成キー Logging:LogLevel:System が生成されます。

ホストをビルドするときに ConfigureAppConfiguration を呼び出して、アプリの構成を指定します。

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

メモリ構成プロバイダー

MemoryConfigurationProvider では、構成のキーと値のペアとして、メモリ内コレクションが使用されます。

次のコードでは、構成システムにメモリコ レクションが追加されています:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

        return Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddInMemoryCollection(Dict);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
}

サンプルのダウンロード の以下のコードでは、上記の構成設定のいくつかが表示されます:

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

上記のコードでは、既定の構成プロバイダーの後に config.AddInMemoryCollection(Dict) が追加されています。 構成プロバイダーの順序付けの例については、「JSON 構成プロバイダー」を参照してください。

MemoryConfigurationProvider を使用した別の例については、配列をバインドを参照してください。

Kestrel エンドポイント構成

Kestrel 固有のエンドポイント構成によって、すべてのサーバー間のエンドポイント構成がオーバーライドされます。 サーバー間のエンドポイント構成には、次のものがあります。

ASP.NET Core Web アプリで使用される次の appsettings.json ファイルについて考えてみましょう。

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

上の強調表示されているマークアップが ASP.NET Core Web アプリで使用され、"かつ" 次のサーバー間エンドポイント構成を使用してコマンド ラインでアプリが起動される場合:

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

Kestrel は、https://localhost:7777 ではなく、 appsettings.json ファイルで Kestrel 専用に構成されたエンドポイント (https://localhost:9999) にバインドされます。

環境変数として構成された Kestrel 固有のエンドポイントを考えてみます。

set Kestrel__Endpoints__Https__Url=https://localhost:8888

上記の環境変数では、Https が Kestrel 固有のエンドポイントの名前です。 前の appsettings.json ファイルでも、Https という名前の Kestrel 固有のエンドポイントが定義されています。 既定で、環境変数構成プロバイダーを使用している環境変数は appsettings. Environment .json の後に読み取られます。したがって、上記の環境変数は Https エンドポイント用に使用されます。

GetValue

ConfigurationBinder.GetValue<T> 指定したキーを使用して、構成から単一の値を抽出し、それを指定した型に変換します:

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

上記のコードでは、NumberKey が構成中に見つからない場合には 99 の既定値が使用されます。

GetSection、GetChildren、Exists

以下の例では、次の MySubsection.json ファイルについて考えます:

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

以下のコードでは、MySubsection セクション を構成プロバイダーに追加します:

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 は、指定されたサブセクションのキーを持つ構成サブセクションを返します。

次のコードは、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"]}'");
    }
}

次のコードは、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"]}'");
    }
}

GetSectionnull を返すことはありません。 一致するセクションが見つからない場合は、空の IConfigurationSection が返されます。

GetSection で一致するセクションが返されると、Value は設定されません。 KeyPath はセクションが存在する場合に返されます。

GetChildren と Exists

次のコードは、IConfiguration.GetChildren を呼び出し、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);
    }
}

上記のコードは、ConfigurationExtensions. Exists を呼び出し、セクションが存在することを確認します:

配列をバインドする

ConfigurationBinder. Bind は、構成キーの配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 数値のキー セグメントを公開する配列形式は、すべて POCO クラスの配列にバインドできます。

サンプル ダウンロードMyArray.json について考えます:

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

次のコードでは、MyArray.json を構成プロバイダーに追加します:

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

次のコードでは、構成を読み取り、値を表示します:

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

上記のコードは、次の出力を返します:

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

上記の出力では、インデックス3の値が value40 になります。これは MyArray. json"4": "value40", に対応しています。 このバインドされた配列インデックスは連続的であり、構成キーインデックスにバインドされていません。 構成バインダーは、バインドされたオブジェクトに null 値をバインドしたり、null エントリを作成したりはできません

次のコードでは、AddInMemoryCollection 拡張メソッドで array:entries 構成を読み込みます:

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

次のコードでは、arrayDict Dictionary の構成を読み取り、値を表示します:

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

上記のコードは、次の出力を返します:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value4
Index: 4  Value: value5

バインドされたオブジェクトのインデックス #3 によって、array:4 構成キーの構成データと、その値 value4 が保持されます。 配列を含む構成データがバインドされている場合、構成キーの配列インデックスは、オブジェクト作成時の構成データの反復のために使用されます。 構成データに null 値を保持することはできません。また、構成キーの配列が 1 つまたは複数のインデックスをスキップしても、バインドされたオブジェクトに null 値のエントリは作成されません。

インデックス#3 に不足している構成項目は、ArrayExample インスタンスにバインドする前に、インデックス#3のキーと値のペアを読み取る構成プロバイダーによってサプライできます。 サンプルダウンロードの、次の Value3.json ファイルについて考えます:

{
  "array:entries:3": "value3"
}

次のコードには、Value3.jsonarrayDict Dictionary の構成が含まれています:

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

次のコードは、上記の構成を読み取り、値を表示します:

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

上記のコードは、次の出力を返します:

Index: 0  Value: value0
Index: 1  Value: value1
Index: 2  Value: value2
Index: 3  Value: value3
Index: 4  Value: value4
Index: 5  Value: value5

カスタム構成プロバイダーが配列のバインドを実装する必要はありません。

カスタム構成プロバイダー

サンプル アプリでは、Entity Framework (EF) を使用してデータベースから構成のキーと値のペアを読み取る、基本的な構成プロバイダーを作成する方法を示します。

プロバイダーの特徴は次のとおりです。

  • EF のメモリ内データベースは、デモンストレーションのために使用されます。 接続文字列を必要とするデータベースを使用するには、第 2 の ConfigurationBuilder を実装して、別の構成プロバイダーからの接続文字列を指定します。
  • プロバイダーは、起動時に、構成にデータベース テーブルを読み取ります。 プロバイダーは、キー単位でデータベースを照会しません。
  • 変更時に再度読み込む機能は実装されていません。このため、アプリの起動後にデータベースを更新しても、アプリの構成には影響がありません。

データベースに構成値を格納するための EFConfigurationValue エンティティを定義します。

Models/EFConfigurationValue.cs:

public class EFConfigurationValue
{
    public string Id { get; set; }
    public string Value { get; set; }
}

構成した値を格納し、その値にアクセスするための EFConfigurationContext を追加します。

EFConfigurationProvider/EFConfigurationContext.cs:

// using Microsoft.EntityFrameworkCore;

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

    public DbSet<EFConfigurationValue> Values { get; set; }
}

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

ConfigurationProvider から継承して、カスタム構成プロバイダーを作成します。 データベースが空だった場合、構成プロバイダーはこれを初期化します。 構成キーでは大文字と小文字が区別されないため、データベースの初期化に使用されるディクショナリは、大文字と小文字を区別しない比較子 (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
        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;
    }
}

AddEFConfiguration 拡張メソッドを使用すると、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));
    }
}

次のコードでは、Program.cs でカスタムの EFConfigurationProvider を使用する方法を示します。

// using Microsoft.EntityFrameworkCore;

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEFConfiguration(
                options => options.UseInMemoryDatabase("InMemoryDb"));
        })

起動時の構成へのアクセス

次のコードでは 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();
        });
    }
}

起動時の簡易メソッドを使用して構成にアクセスする例については、アプリ起動時の簡易メソッドに関連する記事をご覧ください。

Razor ページの構成にアクセスする

次のコードでは Razor ページの構成データが表示されます:

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

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

次のコードでは、MyOptionsConfigure でサービスコンテナーに追加され、構成にバインドされます:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(Configuration.GetSection("MyOptions"));

    services.AddRazorPages();
}

次のマークアップは、@inject Razor ディレクティブを使用して、オプションの値を解決して表示します。

@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>

MVC ビューファイルの構成へのアクセス

次のコードでは、MVC ビューの構成データが表示されます:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

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

デリゲートでオプションを構成する

デリゲートで構成されたオプションは、構成プロバイダーで設定された値をオーバーライドします。

サンプル アプリの例 2 では、デリゲートでオプションを構成しています。

次のコードでは、IConfigureOptions<TOptions> サービスがサービス コンテナーに追加されます。 デリゲートを利用して MyOptions の値が構成されます。

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.Option1 = "Value configured in delegate";
        myOptions.Option2 = 500;
    });

    services.AddRazorPages();
}

このコードには、次のオプションの値が表示されます。

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

先の例では、値 Option1Option2appsettings.json で指定されてから、構成されているデリゲートによりオーバーライドされます。

ホストとアプリの構成

アプリを構成して起動する前に、"ホスト" を構成して起動します。 ホストはアプリの起動と有効期間の管理を担当します。 アプリとホストは、両方ともこのトピックで説明する構成プロバイダーを使用して構成します。 ホスト構成のキーと値のペアも、アプリの構成に含まれます。 ホストをビルドするときの構成プロバイダーの使用方法、およびホストの構成に対する構成ソースの影響について詳しくは、「ASP.NET Core の基礎」をご覧ください。

既定のホスト構成

Web ホストを使用する場合の既定の構成の詳細については、このトピックの ASP.NET Core 2.2 バージョンを参照してください。

  • ホストの構成は、次から提供されます。
    • 環境変数構成プロバイダーを使用する、プレフィックス DOTNET_ (DOTNET_ENVIRONMENT など) が付いた環境変数。 構成のキーと値のペアが読み込まれるときに、プレフィックス (DOTNET_) は削除されます。
    • コマンドライン構成プロバイダーを使用するコマンドライン引数。
  • Web ホストの既定の構成が確立されます (ConfigureWebHostDefaults)。
    • Kestrel は Web サーバーとして使用され、アプリの構成プロバイダーを使用して構成されます。
    • Host Filtering Middleware を追加します。
    • ASPNETCORE_FORWARDEDHEADERS_ENABLED 環境変数が true に設定されている場合は、Forwarded Headers Middleware を追加します。
    • IIS 統合を有効にします。

その他の構成

このトピックは、"アプリの構成" のみに関連しています。 ASP.NET Core アプリの実行とホストに関するその他の側面は、このトピックでは扱わない構成ファイルを使って構成されます。

launchSettings.json に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。

以前のバージョンの ASP.NET からアプリの構成を移行する方法について詳しくは、ASP.NET から ASP.NET Core への移行 をご覧ください。

外部アセンブリから構成を追加する

IHostingStartup の実装により、アプリの Startup クラスの外部にある外部アセンブリから、起動時に拡張機能をアプリに追加できるようになります。 詳細については、「ASP.NET Core でホスティング スタートアップ アセンブリを使用する」を参照してください。

その他の技術情報