ASP.NET Core の構成
作成者: Rick Anderson および Kirk Larkin
注意
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
ASP.NET Core のアプリケーション構成は、1 つまたは複数の構成プロバイダーを使用して実行されます。 構成プロバイダーは、以下のようなさまざまな構成ソースを使用して、キーと値のペアから構成データを読み取ります:
appsettings.json
などの設定ファイル- 環境変数
- Azure Key Vault
- Azure App Configuration
- コマンド ライン引数
- インストール済みまたは作成済みのカスタム プロバイダー
- ディレクトリ ファイル
- メモリ内 .NET オブジェクト
この記事では ASP.NET Core の構成について説明します。 コンソール アプリでの構成の使用方法について詳しくは、.NET 構成に関する記事をご覧ください。
このノードのガイダンスを追加または置き換える Blazor 構成ガイダンスについては、「ASP.NET Core Blazor 構成」をご覧ください。
アプリケーションとホストの構成
ASP.NET Core アプリはホストを構成して起動します。 ホストはアプリの起動と有効期間の管理を担当します。 ASP.NET Core テンプレートを使用すると、ホストを WebApplicationBuilder 含むテンプレートを作成できます。 一部の構成についてはホストおよびアプリケーション構成プロバイダーの両方で行うことができますが、一般には、ホストに必要な構成のみをホスト構成で行う必要があります。
アプリケーションの構成は最も優先度が高く、次のセクションで詳しく説明します。 ホスト構成 はアプリケーション構成に従っています。この記事で説明します。
既定のアプリケーション構成ソース
dotnet new または Visual Studio で作成された ASP.NET Core の web アプリが、次のコードを生成します:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder は、事前に構成された既定値を使用して WebApplicationBuilder クラスの新しいインスタンスを初期化します。 WebApplicationBuilder
(builder
) を初期化すると、優先度の高い方から低い方へ、次の順序でアプリの既定の構成が提供されます。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 接頭辞なしの環境変数構成プロバイダーを使用した接頭辞なしの環境変数。
Development
環境でアプリが実行される場合に使用されるユーザー シークレット。- JSON 構成プロバイダーを使用する
appsettings.{Environment}.json
。 たとえば、appsettings.Production.json
とappsettings.Development.json
です。 - JSON 構成プロバイダーを使用する appsettings.json。
- 次のセクションで説明するホスト構成へのフォールバック。
既定のホスト構成ソース
次の一覧には、WebApplicationBuilder について、優先度が最も高いものから最も低いものまで、既定のホスト構成ソースが含まれています。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 環境変数構成プロバイダーを使用する、プレフィックス
DOTNET_
が付いた環境変数。 - 環境変数構成プロバイダーを使用する、プレフィックス
ASPNETCORE_
が付いた環境変数。
.NET Generic Host と Web Host の場合、既定のホスト構成ソースを、優先度の高いものから順に並べると、次のようになります。
- 環境変数構成プロバイダーを使用する、プレフィックス
ASPNETCORE_
が付いた環境変数。 - コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 環境変数構成プロバイダーを使用する、プレフィックス
DOTNET_
が付いた環境変数。
ホストとアプリケーションの構成で構成値を設定する場合は、アプリケーション構成を使用します。
ホスト変数
次の変数は、ホスト ビルダーを初期化するときに早期にロックされ、アプリケーション構成の影響を受けることはありません。
- アプリケーション名
- 環境名 (例:
Development
、Production
、Staging
) - コンテンツ ルート
- Web ルート
- スタートアップ アセンブリのホスティングをスキャンするかどうか、およびスキャンするアセンブリ。
- IHostBuilder.ConfigureAppConfiguration コールバックの HostBuilderContext.Configuration からアプリおよびライブラリ コードによって読み取られる変数。
その他のホスト設定はすべて、ホスト構成からではなくアプリケーション構成から読み取られます。
URLS
は、ブートストラップ設定ではない多くの一般的なホスト設定の 1 つです。 前の一覧にない他のすべてのホスト設定と同様に、URLS
はアプリケーション構成から後で読み取られます。ホスト構成はアプリケーション構成のフォールバックであるため、ホスト構成を使用して URLS
を設定できますが、appsettings.json
のようにアプリケーション構成内の任意の構成ソースによってオーバーライドされます。
詳細については、「コンテンツ ルート、アプリ名、環境の変更」および「環境変数またはコマンド ラインを使用したコンテンツ ルート、アプリ名、環境の変更、アプリ名、環境の変更」を参照してください。
この記事の残りのセクションでは、アプリケーションの構成を参照してください。
アプリケーション構成プロバイダー
以下のコードでは、追加した順に、有効な構成プロバイダーが表示されます:
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);
}
}
上記の優先度が最も高い既定の構成ソースから最も低い既定の構成ソースまでの一覧では、テンプレートで生成されたアプリケーションに追加される順序とは逆の順序でプロバイダーを示しています。 たとえば、JSON 構成プロバイダーは、コマンドライン構成プロバイダーの前に追加されます。
後から追加された構成プロバイダーは優先度がより高く、それによって、それ以前のキー設定はオーバーライドされます。 たとえば、MyKey
が appsettings.json
と環境の両方で設定されている場合、環境の値が使用されます。 既定の構成プロバイダーを使用すると、コマンドライン構成プロバイダーによって他のすべてのプロバイダーがオーバーライドされます。
CreateBuilder
の詳細については、既定のビルダー設定を参照してください。
appsettings.json
次の appsettings.json
ファイルを考えてみます。
{
"Position": {
"Title": "Editor",
"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 は、以下の順序で構成を読み込みます:
appsettings.json
appsettings.{Environment}.json
:appsettings.Production.json
またはappsettings.Development.json
ファイルなど。 ファイルの環境バージョンは、IHostingEnvironment.EnvironmentNameに基づいて読み込まれます。 詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。
appsettings.{Environment}.json
値によって appsettings.json
内のキーがオーバーライドされます。 たとえば、既定では次のようになります:
- 開発中は、
appsettings.json
で見つかった値はappsettings.Development.json
構成によって上書きされます。 - 運用環境では、
appsettings.json
で見つかった値はappsettings.Production.json
構成によって上書きされます。 たとえば、Azure にアプリをデプロイする場合。
構成値を保証する必要がある場合は、「GetValue」を参照してください。 前の例では文字列が読み取られるだけで、既定値はサポートされていません。
既定の構成を利用する場合、reloadOnChange: true で appsettings.json
ファイルと appsettings.{Environment}.json
ファイルを有効にすることができます。 アプリの開始 "後" に appsettings.json
ファイルと appsettings.{Environment}.json
ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。
appsettings.json のコメント
appsettings.json
および appsettings.{Environment}.json
ファイル内のコメントは、JavaScript または C# スタイルのコメントを使用した場合にサポートされます。
オプションパターンを使用して、階層型の構成データをバインドします
関連する構成値を読み取る方法としては、オプション パターンを使用することをお勧めします。 たとえば、以下の構成値を読み取るには、次のようにします:
"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 構成ファイルへの変更が既定で読み取られます。
"オプション パターン" を使用するときのもう 1 つの方法は、Position
セクションをバインドし、それを依存関係挿入サービス コンテナーに追加することです。 次のコードでは、PositionOptions
は 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: true で appsettings.json
ファイルと appsettings.{Environment}.json
ファイルを有効にすることができます。 アプリの開始 "後" に appsettings.json
ファイルと appsettings.{Environment}.json
ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。
追加の JSON 構成ファイルを追加する方法の詳細については、このドキュメント中の「JSON 構成プロバイダー」を参照してください。
サービス コレクションの結合
サービスを登録し、オプションを構成する以下について考えてみましょう。
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;
}
public static IServiceCollection AddMyDependencyGroup(
this IServiceCollection services)
{
services.AddScoped<IMyDependency, MyDependency>();
services.AddScoped<IMyDependency2, MyDependency2>();
return services;
}
}
}
残りのサービスは、同様のクラスに登録されます。 次のコードでは、新しい拡張メソッドを使用してサービスを登録します。
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 で必要なサービスが追加されます。
セキュリティとユーザー シークレット
構成データのガイドライン:
- 構成プロバイダーのコードやプレーンテキストの構成ファイルには、パスワードなどの機密データを格納しないでください。 Secret Manager ツールを使用すると、開発時にシークレットを格納できます。
- 開発環境やテスト環境では運用シークレットを使用しないでください。
- プロジェクトの外部にシークレットを指定してください。そうすれば、誤ってリソース コード リポジトリにコミットされることはありません。
- 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 詳細については、「 安全な認証フロー」を参照してください。
既定では、ユーザー シークレットの構成ソースは、JSON 構成ソースの後に登録されます。 そのため、ユーザー シークレット キーは appsettings.json
と appsettings.{Environment}.json
のキーよりも優先されます。
パスワードその他の機密データの格納については、次を参照してください:
- ASP.NET Core で複数の環境を使用する
- ASP.NET Core での開発におけるアプリ シークレットの安全な保存: 環境変数を使用して機密データを格納する方法に関するアドバイスが含まれています。 Secret Manager ツールでは、ファイル構成プロバイダーを使用して、ユーザーのシークレットがローカル システム上の JSON ファイルに格納されます。
- Azure Key Vault では、ASP.NET Core アプリのアプリのシークレットが安全に保存されます。 詳細については、「ASP.NET Core の Azure Key Vault 構成プロバイダー」を参照してください。
プレフィックスが付いていない環境変数
プレフィックスが付いていない環境変数は、プレフィックス ASPNETCORE_
または DOTNET_
が付いたもの以外の環境変数です。 たとえば、ASP.NET Core Web アプリケーション テンプレートを使用すると、launchSettings.json
に "ASPNETCORE_ENVIRONMENT": "Development"
が設定されます。 環境変数 ASPNETCORE_
および DOTNET_
の詳細については、次を参照してください。
- プレフィックスなし、プレフィックス
ASPNETCORE_
付き、プレフィックスDOTNETCORE_
付きの環境変数など、最も優先度の高い既定の構成ソースから最も優先度の低い構成ソースまでの一覧。 - Microsoft.Extensions.Hosting の外部で使用される
DOTNET_
環境変数。
既定の構成を使用すると、EnvironmentVariablesConfigurationProvider によって、appsettings.json
、appsettings.{Environment}.json
、およびユーザー シークレットの読み取り後に、環境変数のキーと値のペアから構成が読み込まれます。 そのため、環境から読み取られたキー値によって、appsettings.json
、appsettings.{Environment}.json
、およびユーザー シークレットから読み取られた値がオーバーライドされます。
:
の区切り記号は、すべてのプラットフォームの環境変数階層キーには対応していません。 たとえば、:
の区切り記号は Bash では対応していません。 二重アンダースコア __
は、
- すべてのプラットフォームで対応しています。
- 自動でコロン
:
に置換されます。
次の コマンドは:
- 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();
上のコードでは以下の操作が行われます。
builder.Configuration.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 アプリケーションの設定は:
- rest に暗号化され、暗号化されたチャネルで送信されます。
- 環境変数として公開されます。
詳細については、「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();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
コマンド ライン
既定の構成を使用して、CommandLineConfigurationProvider は、以下の構成ソースの後にコマンド ライン引数のキーと値のペアから構成を読み込みます:
appsettings.json
およびappsettings.{Environment}.json
ファイル。- 開発環境でのアプリ シークレット。
- 環境変数。
既定では、コマンド ラインで設定された構成値は、他のすべての構成プロバイダーで設定された構成値をオーバーライドします。
コマンド ライン引数
次のコマンドは =
を使用してキーと値を設定します:
dotnet run MyKey="Using =" 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": "Editor",
"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」で説明します。
構成キーと値
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
構成キー:
- 構成キーでは、大文字と小文字は区別されません。 たとえば、
ConnectionString
とconnectionstring
は同等のキーとして扱われます。 - キーと値が複数の構成プロバイダーで設定されている場合は、最後に追加されたプロバイダーの値が使用されます。 詳細については、「既定の構成」を参照してください。
- 階層キー
- 構成 API 内では、すべてのプラットフォームでコロン (
:
) の区切りが機能します。 - 環境変数内では、コロン区切りがすべてのプラットフォームでは機能しない場合があります。 ダブル アンダースコア (
__
) はすべてのプラットフォームでサポートされ、コロン:
に自動で変換されます。 - Azure Key Vault では、階層型のキーは区切り記号に
--
を使用します。 シークレットがアプリの構成に読み込まれると、Azure Key Vault 構成プロバイダーによって--
が:
に自動的に置き換えられます。
- 構成 API 内では、すべてのプラットフォームでコロン (
- ConfigurationBinder は、構成キーで配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 配列のバインドについては、「配列をクラスにバインドする」セクションで説明します。
構成値:
- 構成値は文字列です。
- Null 値を構成に格納したり、オブジェクトにバインドしたりすることはできません。
構成プロバイダー
ASP.NET Core アプリで使用できる構成プロバイダーを次の表に示します。
プロバイダー | 以下から構成を提供します |
---|---|
Azure Key Vault 構成プロバイダー | Azure Key Vault |
Azure App Configuration プロバイダー | Azure App Configuration |
コマンド ライン構成プロバイダー | コマンド ライン パラメーター |
カスタム構成プロバイダー | カスタム ソース |
環境変数構成プロバイダー | 環境変数 |
ファイル構成プロバイダー | INI、JSON、および XML ファイル |
ファイルごとのキーの構成プロバイダー | ディレクトリ ファイル |
メモリ構成プロバイダー | メモリ内コレクション |
ユーザー シークレット | ユーザー プロファイル ディレクトリ内のファイル |
構成ソースは、構成プロバイダーで指定された順序で読み取られます。 アプリで必要とされる、基になる構成ソースの優先順位に合わせるために、コード内で構成プロバイダーを並べ替えます。
一般的な一連の構成プロバイダーは次のとおりです。
appsettings.json
appsettings.{Environment}.json
- ユーザー シークレット
- 環境変数構成プロバイダーを使用する環境変数。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
コマンド ライン引数が他のプロバイダーによって設定された構成をオーバーライドできるようにするには、コマンド ラインの構成プロバイダーを一連のプロバイダーの最後に配置するのが一般的です。
上記の一連のプロバイダーは、既定の構成で使用されます。
接続文字列のプレフィックス
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
構成 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 ファイルのキーと値のペアから構成が読み込まれます。
次のコードは、いくつかの構成プロバイダーを追加します。
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();
上記のコードでは、MyIniConfig.ini
および MyIniConfig.{Environment}.ini
ファイルの設定は、以下の設定によってオーバーライドされます:
サンプル ダウンロードには、次の MyIniConfig.ini
ファイルが含まれます。
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.Configuration.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.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();
上記のコードでは、MyXMLFile.xml
および MyXMLFile.{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.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.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 指定したキーを使用して、構成から単一の値を抽出し、それを指定した型に変換します:
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.json
を構成プロバイダーに追加します:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.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"]}'");
}
}
GetSection
が null
を返すことはありません。 一致するセクションが見つからない場合は、空の IConfigurationSection
が返されます。
GetSection
で一致するセクションが返されると、Value は設定されません。 Key と Path はセクションが存在する場合に返されます。
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.Configuration
.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()
{
_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; }
}
上記のコードは、次の出力を返します:
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 エントリを作成したりはできません。
カスタム構成プロバイダー
サンプル アプリでは、Entity Framework (EF) を使用してデータベースから構成のキーと値のペアを読み取る、基本的な構成プロバイダーを作成する方法を示します。
プロバイダーの特徴は次のとおりです。
- EF のメモリ内データベースは、デモンストレーションのために使用されます。 接続文字列を必要とするデータベースを使用するには、第 2 の
ConfigurationBuilder
を実装して、別の構成プロバイダーからの接続文字列を指定します。 - プロバイダーは、起動時に、構成にデータベース テーブルを読み取ります。 プロバイダーは、キー単位でデータベースを照会しません。
- 変更時に再度読み込む機能は実装されていません。このため、アプリの起動後にデータベースを更新しても、アプリの構成には影響がありません。
データベースに構成値を格納するための EFConfigurationValue
エンティティを定義します。
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
構成した値を格納し、その値にアクセスするための EFConfigurationContext
を追加します。
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
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);
}
ConfigurationProvider から継承して、カスタム構成プロバイダーを作成します。 データベースが空だった場合、構成プロバイダーはこれを初期化します。 構成キーでは大文字と小文字が区別されないため、データベースの初期化に使用されるディクショナリは、大文字と小文字を区別しない比較子 (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;
}
}
AddEFConfiguration
拡張メソッドを使用すると、ConfigurationBuilder
に構成ソースを追加できます。
Extensions/EntityFrameworkExtensions.cs
:
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;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
依存関係の挿入 (DI) を使用したアクセス構成
IConfiguration サービスを解決することで、依存関係の挿入 (DI) を使用してサービスに構成を挿入できます。
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
IConfiguration
を使用して値にアクセスする方法については、この記事の「GetValue」と「GetSection、GetChildren、Exists」を参照してください。
Razor ページの構成にアクセスする
次のコードでは Razor ページの構成データが表示されます:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
次のコードでは、MyOptions
は Configure でサービスコンテナーに追加され、構成にバインドされます:
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"]
Program.cs
でのアクセス構成
次のコードは、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();
上記の例の appsettings.json
の場合は、次のようになります。
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
デリゲートでオプションを構成する
デリゲートで構成されたオプションは、構成プロバイダーで設定された値をオーバーライドします。
次のコードでは、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}");
}
}
先の例では、値 Option1
と Option2
が appsettings.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 アプリの実行とホストに関するその他の側面は、このトピックでは扱わない構成ファイルを使って構成されます。
launch.json
/launchSettings.json
は、開発環境用のツール構成ファイルです。以下で説明されています。- 「ASP.NET Core で複数の環境を使用する」内。
- 開発シナリオ用の ASP.NET Core アプリを構成するためにこのファイルが使用されている、ドキュメント セット全体。
web.config
はサーバー構成ファイルです。次のトピックで説明されています。
launchSettings.json
に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。
以前のバージョンの ASP.NET からアプリの構成を移行する方法の詳細については、「ASP.NET から ASP.NET Core に更新する」を参照してください。
外部アセンブリから構成を追加する
IHostingStartup の実装により、アプリの Startup
クラスの外部にある外部アセンブリから、起動時に拡張機能をアプリに追加できるようになります。 詳細については、「ASP.NET Core でホスティング スタートアップ アセンブリを使用する」を参照してください。
構成バインド ソース ジェネレーター
構成バインディング ソース ジェネレーターにより、AOT とトリムに適した構成が提供されます。 詳細については、「構成バインディング ソース ジェネレーター」を参照してください。
その他のリソース
ASP.NET Core のアプリケーション構成は、1 つまたは複数の構成プロバイダーを使用して実行されます。 構成プロバイダーは、以下のようなさまざまな構成ソースを使用して、キーと値のペアから構成データを読み取ります:
appsettings.json
などの設定ファイル- 環境変数
- Azure Key Vault
- Azure App Configuration
- コマンド ライン引数
- インストール済みまたは作成済みのカスタム プロバイダー
- ディレクトリ ファイル
- メモリ内 .NET オブジェクト
この記事では ASP.NET Core の構成について説明します。 コンソール アプリでの構成の使用方法について詳しくは、.NET 構成に関する記事をご覧ください。
アプリケーションとホストの構成
ASP.NET Core アプリはホストを構成して起動します。 ホストはアプリの起動と有効期間の管理を担当します。 ASP.NET Core テンプレートを使用すると、ホストを WebApplicationBuilder 含むテンプレートを作成できます。 一部の構成についてはホストおよびアプリケーション構成プロバイダーの両方で行うことができますが、一般には、ホストに必要な構成のみをホスト構成で行う必要があります。
アプリケーションの構成は最も優先度が高く、次のセクションで詳しく説明します。 ホスト構成 はアプリケーション構成に従っています。この記事で説明します。
既定のアプリケーション構成ソース
dotnet new または Visual Studio で作成された ASP.NET Core の web アプリが、次のコードを生成します:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder は、事前に構成された既定値を使用して WebApplicationBuilder クラスの新しいインスタンスを初期化します。 WebApplicationBuilder
(builder
) を初期化すると、優先度の高い方から低い方へ、次の順序でアプリの既定の構成が提供されます。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 接頭辞なしの環境変数構成プロバイダーを使用した接頭辞なしの環境変数。
Development
環境でアプリが実行される場合に使用されるユーザー シークレット。- JSON 構成プロバイダーを使用する
appsettings.{Environment}.json
。 たとえば、appsettings.Production.json
とappsettings.Development.json
です。 - JSON 構成プロバイダーを使用する appsettings.json。
- 次のセクションで説明するホスト構成へのフォールバック。
既定のホスト構成ソース
次の一覧には、WebApplicationBuilder について、優先度が最も高いものから最も低いものまで、既定のホスト構成ソースが含まれています。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 環境変数構成プロバイダーを使用する、プレフィックス
DOTNET_
が付いた環境変数。 - 環境変数構成プロバイダーを使用する、プレフィックス
ASPNETCORE_
が付いた環境変数。
.NET Generic Host と Web Host の場合、既定のホスト構成ソースを、優先度の高いものから順に並べると、次のようになります。
- 環境変数構成プロバイダーを使用する、プレフィックス
ASPNETCORE_
が付いた環境変数。 - コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 環境変数構成プロバイダーを使用する、プレフィックス
DOTNET_
が付いた環境変数。
ホストとアプリケーションの構成で構成値を設定する場合は、アプリケーション構成を使用します。
ホスト変数
次の変数は、ホスト ビルダーを初期化するときに早期にロックされ、アプリケーション構成の影響を受けることはありません。
- アプリケーション名
- 環境名 (例:
Development
、Production
、Staging
) - コンテンツ ルート
- Web ルート
- スタートアップ アセンブリのホスティングをスキャンするかどうか、およびスキャンするアセンブリ。
- IHostBuilder.ConfigureAppConfiguration コールバックの HostBuilderContext.Configuration からアプリおよびライブラリ コードによって読み取られる変数。
その他のホスト設定はすべて、ホスト構成からではなくアプリケーション構成から読み取られます。
URLS
は、ブートストラップ設定ではない多くの一般的なホスト設定の 1 つです。 前の一覧にない他のすべてのホスト設定と同様に、URLS
はアプリケーション構成から後で読み取られます。ホスト構成はアプリケーション構成のフォールバックであるため、ホスト構成を使用して URLS
を設定できますが、appsettings.json
のようにアプリケーション構成内の任意の構成ソースによってオーバーライドされます。
詳細については、「コンテンツ ルート、アプリ名、環境の変更」および「環境変数またはコマンド ラインを使用したコンテンツ ルート、アプリ名、環境の変更、アプリ名、環境の変更」を参照してください。
この記事の残りのセクションでは、アプリケーションの構成を参照してください。
アプリケーション構成プロバイダー
以下のコードでは、追加した順に、有効な構成プロバイダーが表示されます:
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);
}
}
上記の優先度が最も高い既定の構成ソースから最も低い既定の構成ソースまでの一覧では、テンプレートで生成されたアプリケーションに追加される順序とは逆の順序でプロバイダーを示しています。 たとえば、JSON 構成プロバイダーは、コマンドライン構成プロバイダーの前に追加されます。
後から追加された構成プロバイダーは優先度がより高く、それによって、それ以前のキー設定はオーバーライドされます。 たとえば、MyKey
が appsettings.json
と環境の両方で設定されている場合、環境の値が使用されます。 既定の構成プロバイダーを使用すると、コマンドライン構成プロバイダーによって他のすべてのプロバイダーがオーバーライドされます。
CreateBuilder
の詳細については、既定のビルダー設定を参照してください。
appsettings.json
次の appsettings.json
ファイルを考えてみます。
{
"Position": {
"Title": "Editor",
"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 は、以下の順序で構成を読み込みます:
appsettings.json
appsettings.{Environment}.json
:appsettings.Production.json
またはappsettings.Development.json
ファイルなど。 ファイルの環境バージョンは、IHostingEnvironment.EnvironmentNameに基づいて読み込まれます。 詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。
appsettings.{Environment}.json
値によって appsettings.json
内のキーがオーバーライドされます。 たとえば、既定では次のようになります:
- 開発中は、
appsettings.json
で見つかった値はappsettings.Development.json
構成によって上書きされます。 - 運用環境では、
appsettings.json
で見つかった値はappsettings.Production.json
構成によって上書きされます。 たとえば、Azure にアプリをデプロイする場合。
構成値を保証する必要がある場合は、「GetValue」を参照してください。 前の例では文字列が読み取られるだけで、既定値はサポートされていません。
既定の構成を利用する場合、reloadOnChange: true で appsettings.json
ファイルと appsettings.{Environment}.json
ファイルを有効にすることができます。 アプリの開始 "後" に appsettings.json
ファイルと appsettings.{Environment}.json
ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。
appsettings.json のコメント
appsettings.json
および appsettings.{Environment}.json
ファイル内のコメントは、JavaScript または C# スタイルのコメントを使用した場合にサポートされます。
オプションパターンを使用して、階層型の構成データをバインドします
関連する構成値を読み取る方法としては、オプション パターンを使用することをお勧めします。 たとえば、以下の構成値を読み取るには、次のようにします:
"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 構成ファイルへの変更が既定で読み取られます。
"オプション パターン" を使用するときのもう 1 つの方法は、Position
セクションをバインドし、それを依存関係挿入サービス コンテナーに追加することです。 次のコードでは、PositionOptions
は 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: true で appsettings.json
ファイルと appsettings.{Environment}.json
ファイルを有効にすることができます。 アプリの開始 "後" に appsettings.json
ファイルと appsettings.{Environment}.json
ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。
追加の JSON 構成ファイルを追加する方法の詳細については、このドキュメント中の「JSON 構成プロバイダー」を参照してください。
サービス コレクションの結合
サービスを登録し、オプションを構成する以下について考えてみましょう。
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;
}
public static IServiceCollection AddMyDependencyGroup(
this IServiceCollection services)
{
services.AddScoped<IMyDependency, MyDependency>();
services.AddScoped<IMyDependency2, MyDependency2>();
return services;
}
}
}
残りのサービスは、同様のクラスに登録されます。 次のコードでは、新しい拡張メソッドを使用してサービスを登録します。
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 で必要なサービスが追加されます。
セキュリティとユーザー シークレット
構成データのガイドライン:
- 構成プロバイダーのコードやプレーンテキストの構成ファイルには、パスワードなどの機密データを格納しないでください。 Secret Manager ツールを使用すると、開発時にシークレットを格納できます。
- 開発環境やテスト環境では運用シークレットを使用しないでください。
- プロジェクトの外部にシークレットを指定してください。そうすれば、誤ってリソース コード リポジトリにコミットされることはありません。
- 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 詳細については、「 安全な認証フロー」を参照してください。
既定では、ユーザー シークレットの構成ソースは、JSON 構成ソースの後に登録されます。 そのため、ユーザー シークレット キーは appsettings.json
と appsettings.{Environment}.json
のキーよりも優先されます。
パスワードその他の機密データの格納については、次を参照してください:
- ASP.NET Core で複数の環境を使用する
- ASP.NET Core での開発におけるアプリ シークレットの安全な保存: 環境変数を使用して機密データを格納する方法に関するアドバイスが含まれています。 Secret Manager ツールでは、ファイル構成プロバイダーを使用して、ユーザーのシークレットがローカル システム上の JSON ファイルに格納されます。
Azure Key Vault では、ASP.NET Core アプリのアプリのシークレットが安全に保存されます。 詳細については、「ASP.NET Core の Azure Key Vault 構成プロバイダー」を参照してください。
プレフィックスが付いていない環境変数
プレフィックスが付いていない環境変数は、プレフィックス ASPNETCORE_
または DOTNET_
が付いたもの以外の環境変数です。 たとえば、ASP.NET Core Web アプリケーション テンプレートを使用すると、launchSettings.json
に "ASPNETCORE_ENVIRONMENT": "Development"
が設定されます。 環境変数 ASPNETCORE_
および DOTNET_
の詳細については、次を参照してください。
- プレフィックスなし、プレフィックス
ASPNETCORE_
付き、プレフィックスDOTNETCORE_
付きの環境変数など、最も優先度の高い既定の構成ソースから最も優先度の低い構成ソースまでの一覧。 - Microsoft.Extensions.Hosting の外部で使用される
DOTNET_
環境変数。
既定の構成を使用すると、EnvironmentVariablesConfigurationProvider によって、appsettings.json
、appsettings.{Environment}.json
、およびユーザー シークレットの読み取り後に、環境変数のキーと値のペアから構成が読み込まれます。 そのため、環境から読み取られたキー値によって、appsettings.json
、appsettings.{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();
上のコードでは以下の操作が行われます。
builder.Configuration.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 アプリケーションの設定は:
- rest に暗号化され、暗号化されたチャネルで送信されます。
- 環境変数として公開されます。
詳細については、「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();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
コマンド ライン
既定の構成を使用して、CommandLineConfigurationProvider は、以下の構成ソースの後にコマンド ライン引数のキーと値のペアから構成を読み込みます:
appsettings.json
およびappsettings.{Environment}.json
ファイル。- 開発環境でのアプリ シークレット。
- 環境変数。
既定では、コマンド ラインで設定された構成値は、他のすべての構成プロバイダーで設定された構成値をオーバーライドします。
コマンド ライン引数
次のコマンドは =
を使用してキーと値を設定します:
dotnet run MyKey="Using =" 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": "Editor",
"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」で説明します。
構成キーと値
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
構成キー:
- 構成キーでは、大文字と小文字は区別されません。 たとえば、
ConnectionString
とconnectionstring
は同等のキーとして扱われます。 - キーと値が複数の構成プロバイダーで設定されている場合は、最後に追加されたプロバイダーの値が使用されます。 詳細については、「既定の構成」を参照してください。
- 階層キー
- 構成 API 内では、すべてのプラットフォームでコロン (
:
) の区切りが機能します。 - 環境変数内では、コロン区切りがすべてのプラットフォームでは機能しない場合があります。 ダブル アンダースコア (
__
) はすべてのプラットフォームでサポートされ、コロン:
に自動で変換されます。 - Azure Key Vault では、階層型のキーは区切り記号に
--
を使用します。 シークレットがアプリの構成に読み込まれると、Azure Key Vault 構成プロバイダーによって--
が:
に自動的に置き換えられます。
- 構成 API 内では、すべてのプラットフォームでコロン (
- ConfigurationBinder は、構成キーで配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 配列のバインドについては、「配列をクラスにバインドする」セクションで説明します。
構成値:
- 構成値は文字列です。
- Null 値を構成に格納したり、オブジェクトにバインドしたりすることはできません。
構成プロバイダー
ASP.NET Core アプリで使用できる構成プロバイダーを次の表に示します。
プロバイダー | 以下から構成を提供します |
---|---|
Azure Key Vault 構成プロバイダー | Azure Key Vault |
Azure App Configuration プロバイダー | Azure App Configuration |
コマンド ライン構成プロバイダー | コマンド ライン パラメーター |
カスタム構成プロバイダー | カスタム ソース |
環境変数構成プロバイダー | 環境変数 |
ファイル構成プロバイダー | INI、JSON、および XML ファイル |
ファイルごとのキーの構成プロバイダー | ディレクトリ ファイル |
メモリ構成プロバイダー | メモリ内コレクション |
ユーザー シークレット | ユーザー プロファイル ディレクトリ内のファイル |
構成ソースは、構成プロバイダーで指定された順序で読み取られます。 アプリで必要とされる、基になる構成ソースの優先順位に合わせるために、コード内で構成プロバイダーを並べ替えます。
一般的な一連の構成プロバイダーは次のとおりです。
appsettings.json
appsettings.{Environment}.json
- ユーザー シークレット
- 環境変数構成プロバイダーを使用する環境変数。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
コマンド ライン引数が他のプロバイダーによって設定された構成をオーバーライドできるようにするには、コマンド ラインの構成プロバイダーを一連のプロバイダーの最後に配置するのが一般的です。
上記の一連のプロバイダーは、既定の構成で使用されます。
接続文字列のプレフィックス
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
構成 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 ファイルのキーと値のペアから構成が読み込まれます。
次のコードは、いくつかの構成プロバイダーを追加します。
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();
上記のコードでは、MyIniConfig.ini
および MyIniConfig.{Environment}.ini
ファイルの設定は、以下の設定によってオーバーライドされます:
サンプル ダウンロードには、次の MyIniConfig.ini
ファイルが含まれます。
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.Configuration.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.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();
上記のコードでは、MyXMLFile.xml
および MyXMLFile.{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.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.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 指定したキーを使用して、構成から単一の値を抽出し、それを指定した型に変換します:
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.json
を構成プロバイダーに追加します:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.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"]}'");
}
}
GetSection
が null
を返すことはありません。 一致するセクションが見つからない場合は、空の IConfigurationSection
が返されます。
GetSection
で一致するセクションが返されると、Value は設定されません。 Key と Path はセクションが存在する場合に返されます。
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.Configuration
.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()
{
_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; }
}
上記のコードは、次の出力を返します:
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 エントリを作成したりはできません。
カスタム構成プロバイダー
サンプル アプリでは、Entity Framework (EF) を使用してデータベースから構成のキーと値のペアを読み取る、基本的な構成プロバイダーを作成する方法を示します。
プロバイダーの特徴は次のとおりです。
- EF のメモリ内データベースは、デモンストレーションのために使用されます。 接続文字列を必要とするデータベースを使用するには、第 2 の
ConfigurationBuilder
を実装して、別の構成プロバイダーからの接続文字列を指定します。 - プロバイダーは、起動時に、構成にデータベース テーブルを読み取ります。 プロバイダーは、キー単位でデータベースを照会しません。
- 変更時に再度読み込む機能は実装されていません。このため、アプリの起動後にデータベースを更新しても、アプリの構成には影響がありません。
データベースに構成値を格納するための EFConfigurationValue
エンティティを定義します。
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
構成した値を格納し、その値にアクセスするための EFConfigurationContext
を追加します。
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
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);
}
ConfigurationProvider から継承して、カスタム構成プロバイダーを作成します。 データベースが空だった場合、構成プロバイダーはこれを初期化します。 構成キーでは大文字と小文字が区別されないため、データベースの初期化に使用されるディクショナリは、大文字と小文字を区別しない比較子 (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;
}
}
AddEFConfiguration
拡張メソッドを使用すると、ConfigurationBuilder
に構成ソースを追加できます。
Extensions/EntityFrameworkExtensions.cs
:
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;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
依存関係の挿入 (DI) を使用したアクセス構成
IConfiguration サービスを解決することで、依存関係の挿入 (DI) を使用してサービスに構成を挿入できます。
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
IConfiguration
を使用して値にアクセスする方法については、この記事の「GetValue」と「GetSection、GetChildren、Exists」を参照してください。
Razor ページの構成にアクセスする
次のコードでは Razor ページの構成データが表示されます:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
次のコードでは、MyOptions
は Configure でサービスコンテナーに追加され、構成にバインドされます:
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"]
Program.cs
でのアクセス構成
次のコードは、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();
上記の例の appsettings.json
の場合は、次のようになります。
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
デリゲートでオプションを構成する
デリゲートで構成されたオプションは、構成プロバイダーで設定された値をオーバーライドします。
次のコードでは、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}");
}
}
先の例では、値 Option1
と Option2
が appsettings.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 アプリの実行とホストに関するその他の側面は、このトピックでは扱わない構成ファイルを使って構成されます。
launch.json
/launchSettings.json
は、開発環境用のツール構成ファイルです。以下で説明されています。- 「ASP.NET Core で複数の環境を使用する」内。
- 開発シナリオ用の ASP.NET Core アプリを構成するためにこのファイルが使用されている、ドキュメント セット全体。
web.config
はサーバー構成ファイルです。次のトピックで説明されています。
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 構成に関する記事をご覧ください。
アプリケーションとホストの構成
ASP.NET Core アプリはホストを構成して起動します。 ホストはアプリの起動と有効期間の管理を担当します。 ASP.NET Core テンプレートを使用すると、ホストを WebApplicationBuilder 含むテンプレートを作成できます。 一部の構成についてはホストおよびアプリケーション構成プロバイダーの両方で行うことができますが、一般には、ホストに必要な構成のみをホスト構成で行う必要があります。
アプリケーションの構成は最も優先度が高く、次のセクションで詳しく説明します。 ホスト構成 はアプリケーション構成に従っています。この記事で説明します。
既定のアプリケーション構成ソース
dotnet new または Visual Studio で作成された ASP.NET Core の web アプリが、次のコードを生成します:
var builder = WebApplication.CreateBuilder(args);
WebApplication.CreateBuilder は、事前に構成された既定値を使用して WebApplicationBuilder クラスの新しいインスタンスを初期化します。 WebApplicationBuilder
(builder
) を初期化すると、優先度の高い方から低い方へ、次の順序でアプリの既定の構成が提供されます。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 接頭辞なしの環境変数構成プロバイダーを使用した接頭辞なしの環境変数。
Development
環境でアプリが実行される場合に使用されるユーザー シークレット。- JSON 構成プロバイダーを使用する
appsettings.{Environment}.json
。 たとえば、appsettings.Production.json
とappsettings.Development.json
です。 - JSON 構成プロバイダーを使用する appsettings.json。
- 次のセクションで説明するホスト構成へのフォールバック。
既定のホスト構成ソース
次の一覧には、優先度が最も高いものから最も低いものまで、既定のホスト構成ソースが含まれています。
- 環境変数構成プロバイダーを使用する、プレフィックス
ASPNETCORE_
が付いた環境変数。 - コマンドライン構成プロバイダーを使用するコマンドライン引数。
- 環境変数構成プロバイダーを使用する、プレフィックス
DOTNET_
が付いた環境変数。
ホストとアプリケーションの構成で構成値を設定する場合は、アプリケーション構成を使用します。
ホスト構成でプレフィックス ASPNETCORE_
が付いた環境変数がコマンドライン引数よりも優先される理由の説明については、この GitHub コメントの説明を参照してください。
ホスト変数
次の変数は、ホスト ビルダーを初期化するときに早期にロックされ、アプリケーション構成の影響を受けることはありません。
- アプリケーション名
- 環境名 (例:
Development
、Production
、Staging
) - コンテンツ ルート
- Web ルート
- スタートアップ アセンブリのホスティングをスキャンするかどうか、およびスキャンするアセンブリ。
- IHostBuilder.ConfigureAppConfiguration コールバックの HostBuilderContext.Configuration からアプリおよびライブラリ コードによって読み取られる変数。
その他のホスト設定はすべて、ホスト構成からではなくアプリケーション構成から読み取られます。
URLS
は、ブートストラップ設定ではない多くの一般的なホスト設定の 1 つです。 前の一覧にない他のすべてのホスト設定と同様に、URLS
はアプリケーション構成から後で読み取られます。ホスト構成はアプリケーション構成のフォールバックであるため、ホスト構成を使用して URLS
を設定できますが、appsettings.json
のようにアプリケーション構成内の任意の構成ソースによってオーバーライドされます。
詳細については、「コンテンツ ルート、アプリ名、環境の変更」および「環境変数またはコマンド ラインを使用したコンテンツ ルート、アプリ名、環境の変更、アプリ名、環境の変更」を参照してください。
この記事の残りのセクションでは、アプリケーションの構成を参照してください。
アプリケーション構成プロバイダー
以下のコードでは、追加した順に、有効な構成プロバイダーが表示されます:
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);
}
}
上記の優先度が最も高い既定の構成ソースから最も低い既定の構成ソースまでの一覧では、テンプレートで生成されたアプリケーションに追加される順序とは逆の順序でプロバイダーを示しています。 たとえば、JSON 構成プロバイダーは、コマンドライン構成プロバイダーの前に追加されます。
後から追加された構成プロバイダーは優先度がより高く、それによって、それ以前のキー設定はオーバーライドされます。 たとえば、MyKey
が appsettings.json
と環境の両方で設定されている場合、環境の値が使用されます。 既定の構成プロバイダーを使用すると、コマンドライン構成プロバイダーによって他のすべてのプロバイダーがオーバーライドされます。
CreateBuilder
の詳細については、既定のビルダー設定を参照してください。
appsettings.json
次の appsettings.json
ファイルを考えてみます。
{
"Position": {
"Title": "Editor",
"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 は、以下の順序で構成を読み込みます:
appsettings.json
appsettings.{Environment}.json
:appsettings.Production.json
またはappsettings.Development.json
ファイルなど。 ファイルの環境バージョンは、IHostingEnvironment.EnvironmentNameに基づいて読み込まれます。 詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。
appsettings.{Environment}.json
値によって appsettings.json
内のキーがオーバーライドされます。 たとえば、既定では次のようになります:
- 開発中は、
appsettings.json
で見つかった値はappsettings.Development.json
構成によって上書きされます。 - 運用環境では、
appsettings.json
で見つかった値はappsettings.Production.json
構成によって上書きされます。 たとえば、Azure にアプリをデプロイする場合。
構成値を保証する必要がある場合は、「GetValue」を参照してください。 前の例では文字列が読み取られるだけで、既定値はサポートされていません。
既定の構成を利用する場合、reloadOnChange: true で appsettings.json
ファイルと appsettings.{Environment}.json
ファイルを有効にすることができます。 アプリの開始 "後" に appsettings.json
ファイルと appsettings.{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 構成ファイルへの変更が既定で読み取られます。
"オプション パターン" を使用するときのもう 1 つの方法は、Position
セクションをバインドし、それを依存関係挿入サービス コンテナーに追加することです。 次のコードでは、PositionOptions
は 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: true で appsettings.json
ファイルと appsettings.{Environment}.json
ファイルを有効にすることができます。 アプリの開始 "後" に appsettings.json
ファイルと appsettings.{Environment}.json
ファイルに加えられた変更は、JSON 構成プロバイダーによって読み取られます。
追加の JSON 構成ファイルを追加する方法の詳細については、このドキュメント中の「JSON 構成プロバイダー」を参照してください。
サービス コレクションの結合
サービスを登録し、オプションを構成する以下について考えてみましょう。
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;
}
public static IServiceCollection AddMyDependencyGroup(
this IServiceCollection services)
{
services.AddScoped<IMyDependency, MyDependency>();
services.AddScoped<IMyDependency2, MyDependency2>();
return services;
}
}
}
残りのサービスは、同様のクラスに登録されます。 次のコードでは、新しい拡張メソッドを使用してサービスを登録します。
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 で必要なサービスが追加されます。
セキュリティとユーザー シークレット
構成データのガイドライン:
- 構成プロバイダーのコードやプレーンテキストの構成ファイルには、パスワードなどの機密データを格納しないでください。 Secret Manager ツールを使用すると、開発時にシークレットを格納できます。
- 開発環境やテスト環境では運用シークレットを使用しないでください。
- プロジェクトの外部にシークレットを指定してください。そうすれば、誤ってリソース コード リポジトリにコミットされることはありません。
- 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 詳細については、「 安全な認証フロー」を参照してください。
既定では、ユーザー シークレットの構成ソースは、JSON 構成ソースの後に登録されます。 そのため、ユーザー シークレット キーは appsettings.json
と appsettings.{Environment}.json
のキーよりも優先されます。
パスワードその他の機密データの格納については、次を参照してください:
- ASP.NET Core で複数の環境を使用する
- ASP.NET Core での開発におけるアプリ シークレットの安全な保存: 環境変数を使用して機密データを格納する方法に関するアドバイスが含まれています。 Secret Manager ツールでは、ファイル構成プロバイダーを使用して、ユーザーのシークレットがローカル システム上の JSON ファイルに格納されます。
Azure Key Vault では、ASP.NET Core アプリのアプリのシークレットが安全に保存されます。 詳細については、「ASP.NET Core の Azure Key Vault 構成プロバイダー」を参照してください。
プレフィックスが付いていない環境変数
プレフィックスが付いていない環境変数は、プレフィックス ASPNETCORE_
または DOTNET_
が付いたもの以外の環境変数です。 たとえば、ASP.NET Core Web アプリケーション テンプレートを使用すると、launchSettings.json
に "ASPNETCORE_ENVIRONMENT": "Development"
が設定されます。 環境変数 ASPNETCORE_
および DOTNET_
の詳細については、次を参照してください。
- プレフィックスなし、プレフィックス
ASPNETCORE_
付き、プレフィックスDOTNETCORE_
付きの環境変数など、最も優先度の高い既定の構成ソースから最も優先度の低い構成ソースまでの一覧。 - Microsoft.Extensions.Hosting の外部で使用される
DOTNET_
環境変数。
既定の構成を使用すると、EnvironmentVariablesConfigurationProvider によって、appsettings.json
、appsettings.{Environment}.json
、およびユーザー シークレットの読み取り後に、環境変数のキーと値のペアから構成が読み込まれます。 そのため、環境から読み取られたキー値によって、appsettings.json
、appsettings.{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();
上のコードでは以下の操作が行われます。
builder.Configuration.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 アプリケーションの設定は:
- rest に暗号化され、暗号化されたチャネルで送信されます。
- 環境変数として公開されます。
詳細については、「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();
foreach (var c in builder.Configuration.AsEnumerable())
{
Console.WriteLine(c.Key + " = " + c.Value);
}
コマンド ライン
既定の構成を使用して、CommandLineConfigurationProvider は、以下の構成ソースの後にコマンド ライン引数のキーと値のペアから構成を読み込みます:
appsettings.json
およびappsettings.{Environment}.json
ファイル。- 開発環境でのアプリ シークレット。
- 環境変数。
既定では、コマンド ラインで設定された構成値は、他のすべての構成プロバイダーで設定された構成値をオーバーライドします。
コマンド ライン引数
次のコマンドは =
を使用してキーと値を設定します:
dotnet run MyKey="Using =" 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": "Editor",
"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」で説明します。
構成キーと値
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
構成キー:
- 構成キーでは、大文字と小文字は区別されません。 たとえば、
ConnectionString
とconnectionstring
は同等のキーとして扱われます。 - キーと値が複数の構成プロバイダーで設定されている場合は、最後に追加されたプロバイダーの値が使用されます。 詳細については、「既定の構成」を参照してください。
- 階層キー
- 構成 API 内では、すべてのプラットフォームでコロン (
:
) の区切りが機能します。 - 環境変数内では、コロン区切りがすべてのプラットフォームでは機能しない場合があります。 ダブル アンダースコア (
__
) はすべてのプラットフォームでサポートされ、コロン:
に自動で変換されます。 - Azure Key Vault では、階層型のキーは区切り記号に
--
を使用します。 シークレットがアプリの構成に読み込まれると、Azure Key Vault 構成プロバイダーによって--
が:
に自動的に置き換えられます。
- 構成 API 内では、すべてのプラットフォームでコロン (
- ConfigurationBinder は、構成キーで配列インデックスを使用して、オブジェクトに対する配列のバインドをサポートしています。 配列のバインドについては、「配列をクラスにバインドする」セクションで説明します。
構成値:
- 構成値は文字列です。
- Null 値を構成に格納したり、オブジェクトにバインドしたりすることはできません。
構成プロバイダー
ASP.NET Core アプリで使用できる構成プロバイダーを次の表に示します。
プロバイダー | 以下から構成を提供します |
---|---|
Azure Key Vault 構成プロバイダー | Azure Key Vault |
Azure App Configuration プロバイダー | Azure App Configuration |
コマンド ライン構成プロバイダー | コマンド ライン パラメーター |
カスタム構成プロバイダー | カスタム ソース |
環境変数構成プロバイダー | 環境変数 |
ファイル構成プロバイダー | INI、JSON、および XML ファイル |
ファイルごとのキーの構成プロバイダー | ディレクトリ ファイル |
メモリ構成プロバイダー | メモリ内コレクション |
ユーザー シークレット | ユーザー プロファイル ディレクトリ内のファイル |
構成ソースは、構成プロバイダーで指定された順序で読み取られます。 アプリで必要とされる、基になる構成ソースの優先順位に合わせるために、コード内で構成プロバイダーを並べ替えます。
一般的な一連の構成プロバイダーは次のとおりです。
appsettings.json
appsettings.{Environment}.json
- ユーザー シークレット
- 環境変数構成プロバイダーを使用する環境変数。
- コマンドライン構成プロバイダーを使用するコマンドライン引数。
コマンド ライン引数が他のプロバイダーによって設定された構成をオーバーライドできるようにするには、コマンド ラインの構成プロバイダーを一連のプロバイダーの最後に配置するのが一般的です。
上記の一連のプロバイダーは、既定の構成で使用されます。
接続文字列のプレフィックス
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
構成 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 ファイルのキーと値のペアから構成が読み込まれます。
次のコードは、いくつかの構成プロバイダーを追加します。
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();
上記のコードでは、MyIniConfig.ini
および MyIniConfig.{Environment}.ini
ファイルの設定は、以下の設定によってオーバーライドされます:
サンプル ダウンロードには、次の MyIniConfig.ini
ファイルが含まれます。
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.Configuration.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.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();
上記のコードでは、MyXMLFile.xml
および MyXMLFile.{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.Configuration.AddInMemoryCollection(Dict);
builder.Configuration.AddEnvironmentVariables();
builder.Configuration.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 指定したキーを使用して、構成から単一の値を抽出し、それを指定した型に変換します:
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.json
を構成プロバイダーに追加します:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration
.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"]}'");
}
}
GetSection
が null
を返すことはありません。 一致するセクションが見つからない場合は、空の IConfigurationSection
が返されます。
GetSection
で一致するセクションが返されると、Value は設定されません。 Key と Path はセクションが存在する場合に返されます。
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.Configuration
.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()
{
_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; }
}
上記のコードは、次の出力を返します:
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 エントリを作成したりはできません。
カスタム構成プロバイダー
サンプル アプリでは、Entity Framework (EF) を使用してデータベースから構成のキーと値のペアを読み取る、基本的な構成プロバイダーを作成する方法を示します。
プロバイダーの特徴は次のとおりです。
- EF のメモリ内データベースは、デモンストレーションのために使用されます。 接続文字列を必要とするデータベースを使用するには、第 2 の
ConfigurationBuilder
を実装して、別の構成プロバイダーからの接続文字列を指定します。 - プロバイダーは、起動時に、構成にデータベース テーブルを読み取ります。 プロバイダーは、キー単位でデータベースを照会しません。
- 変更時に再度読み込む機能は実装されていません。このため、アプリの起動後にデータベースを更新しても、アプリの構成には影響がありません。
データベースに構成値を格納するための EFConfigurationValue
エンティティを定義します。
Models/EFConfigurationValue.cs
:
public class EFConfigurationValue
{
public string Id { get; set; } = String.Empty;
public string Value { get; set; } = String.Empty;
}
構成した値を格納し、その値にアクセスするための EFConfigurationContext
を追加します。
EFConfigurationProvider/EFConfigurationContext.cs
:
public class EFConfigurationContext : DbContext
{
public EFConfigurationContext(DbContextOptions<EFConfigurationContext> options) : base(options)
{
}
public DbSet<EFConfigurationValue> Values => Set<EFConfigurationValue>();
}
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);
}
ConfigurationProvider から継承して、カスタム構成プロバイダーを作成します。 データベースが空だった場合、構成プロバイダーはこれを初期化します。 構成キーでは大文字と小文字が区別されないため、データベースの初期化に使用されるディクショナリは、大文字と小文字を区別しない比較子 (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;
}
}
AddEFConfiguration
拡張メソッドを使用すると、ConfigurationBuilder
に構成ソースを追加できます。
Extensions/EntityFrameworkExtensions.cs
:
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;
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEFConfiguration(
opt => opt.UseInMemoryDatabase("InMemoryDb"));
var app = builder.Build();
app.Run();
依存関係の挿入 (DI) を使用したアクセス構成
IConfiguration サービスを解決することで、依存関係の挿入 (DI) を使用してサービスに構成を挿入できます。
public class Service
{
private readonly IConfiguration _config;
public Service(IConfiguration config) =>
_config = config;
public void DoSomething()
{
var configSettingValue = _config["ConfigSetting"];
// ...
}
}
IConfiguration
を使用して値にアクセスする方法については、この記事の「GetValue」と「GetSection、GetChildren、Exists」を参照してください。
Razor ページの構成にアクセスする
次のコードでは Razor ページの構成データが表示されます:
@page
@model Test5Model
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
Configuration value for 'MyKey': @Configuration["MyKey"]
次のコードでは、MyOptions
は Configure でサービスコンテナーに追加され、構成にバインドされます:
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"]
Program.cs
でのアクセス構成
次のコードは、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();
上記の例の appsettings.json
の場合は、次のようになります。
{
...
"KeyOne": "Key One Value",
"KeyTwo": 1999,
"KeyThree": true
}
デリゲートでオプションを構成する
デリゲートで構成されたオプションは、構成プロバイダーで設定された値をオーバーライドします。
次のコードでは、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}");
}
}
先の例では、値 Option1
と Option2
が appsettings.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 アプリの実行とホストに関するその他の側面は、このトピックでは扱わない構成ファイルを使って構成されます。
launch.json
/launchSettings.json
は、開発環境用のツール構成ファイルです。以下で説明されています。- 「ASP.NET Core で複数の環境を使用する」内。
- 開発シナリオ用の ASP.NET Core アプリを構成するためにこのファイルが使用されている、ドキュメント セット全体。
web.config
はサーバー構成ファイルです。次のトピックで説明されています。
launchSettings.json
に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。
以前のバージョンの ASP.NET からアプリの構成を移行する方法の詳細については、「ASP.NET から ASP.NET Core に更新する」を参照してください。
外部アセンブリから構成を追加する
IHostingStartup の実装により、アプリの Startup
クラスの外部にある外部アセンブリから、起動時に拡張機能をアプリに追加できるようになります。 詳細については、「ASP.NET Core でホスティング スタートアップ アセンブリを使用する」を参照してください。
その他の技術情報
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 は指定したキーを使用して、構成から単一の値を抽出し、それを指定した型に変換します。 このメソッドは 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}");
}
}
上記のコードでは、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.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("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"]}'");
}
}
GetSection
が null
を返すことはありません。 一致するセクションが見つからない場合は、空の IConfigurationSection
が返されます。
GetSection
で一致するセクションが返されると、Value は設定されません。 Key と Path はセクションが存在する場合に返されます。
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.json
と arrayDict
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
カスタム構成プロバイダーが配列のバインドを実装する必要はありません。
カスタム構成プロバイダー
警告
この記事では、接続文字列の使用方法について説明します。 ローカル データベースでは、ユーザーを認証する必要はありませんが、運用環境では、接続文字列認証用のパスワードが含まれる場合があります。 リソース所有者パスワード資格情報 (ROPC) は、運用データベースで回避する必要があるセキュリティ リスクです。 運用アプリでは、使用可能な最も安全な認証フローを使用する必要があります。 テスト環境または運用環境にデプロイされたアプリの認証の詳細については、「 安全な認証フロー」を参照してください。
サンプル アプリでは、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-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;
}
}
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"]
次のコードでは、MyOptions
は Configure でサービスコンテナーに追加され、構成にバインドされます:
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}");
}
}
先の例では、値 Option1
と Option2
が appsettings.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 アプリの実行とホストに関するその他の側面は、このトピックでは扱わない構成ファイルを使って構成されます。
launch.json
/launchSettings.json
は、開発環境用のツール構成ファイルです。以下で説明されています。- 「ASP.NET Core で複数の環境を使用する」内。
- 開発シナリオ用の ASP.NET Core アプリを構成するためにこのファイルが使用されている、ドキュメント セット全体。
web.config
はサーバー構成ファイルです。次のトピックで説明されています。
launchSettings.json
に設定されている環境変数で、システム環境に設定されているそれらがオーバーライドされます。
以前のバージョンの ASP.NET からアプリの構成を移行する方法の詳細については、「ASP.NET から ASP.NET Core に更新する」を参照してください。
外部アセンブリから構成を追加する
IHostingStartup の実装により、アプリの Startup
クラスの外部にある外部アセンブリから、起動時に拡張機能をアプリに追加できるようになります。 詳細については、「ASP.NET Core でホスティング スタートアップ アセンブリを使用する」を参照してください。
その他の技術情報
ASP.NET Core