ASP.NET Core Blazor の構成

注意

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の ASP.NET Core 8.0 バージョンをご参照ください。

この記事では、アプリの設定、認証、ログの構成など、Blazor アプリの構成方法について説明します。

このガイダンスは以下に適用されます。

  • Blazor Web アプリでの対話型 WebAssembly レンダリング。
  • Blazor WebAssembly アプリ。

ドキュメント コンポーネントの例では、通常、対話型レンダリング モードの構成は、コンポーネントの定義ファイル (.razor) 内の @rendermode ディレクティブを使用しては行いません。

  • Blazor Web アプリにおいて、コンポーネントには、コンポーネントの定義ファイル内で、または親コンポーネントから継承された対話型レンダリング モードが適用されている必要があります。 詳細については、「ASP.NET Core Blazor レンダリング モード」を参照してください。

  • スタンドアロン Blazor WebAssembly アプリでは、コンポーネントは示されているように機能し、Blazor WebAssembly アプリ内の WebAssembly 上で常に対話形式で実行されるため、レンダリング モードは必要ありません。

対話型 WebAssembly または対話型自動のレンダリング モードを使うときは、すべてのコンポーネント コードがコンパイルされてクライアントに送信されることに注意してください。そうすれば、ユーザーがそれを逆コンパイルして検査できます。 プライベート コード、アプリ シークレット、またはその他の機密情報をクライアント側でレンダリングされるコンポーネントに置かないでください。

  • ホストされている Blazor WebAssembly ソリューションの Client プロジェクト。
  • Blazor WebAssembly アプリ。

ファイルとフォルダーの目的と場所に関するガイダンスについては、「ASP.NET Core Blazor プロジェクトの構造」をご参照ください。参照先では、Blazor 開始スクリプトの場所と、<head><body> コンテンツの場所についても説明されています。

デモ コードを実行する最善の方法は、ターゲットの .NET のバージョンと一致する Blazor サンプル GitHub リポジトリから、BlazorSample_{PROJECT TYPE} のサンプル アプリをダウンロードすることです。 現時点では、すべてのドキュメント例が同じサンプル アプリに含まれているわけではありませんが、現在 .NET 8 の記事の例のほとんどをサンプル アプリへと移行する作業が行われています。 この作業は、2024 年の第 1 四半期に完了する予定です。

サーバー側の ASP.NET Core アプリの構成については、「ASP.NET Core の構成」をご覧ください。

クライアント側は、既定で次のアプリ設定ファイルから構成が読み込まれます。

  • wwwroot/appsettings.json
  • wwwroot/appsettings.{ENVIRONMENT}.json。ここで、{ENVIRONMENT} プレースホルダーはアプリのランタイム環境です。

メモ

wwwroot のアプリ設定ファイルに配置されたログ構成は、既定では読み込まれません。 詳しくは、後の「ログの構成」セクションをご覧ください。

Azure サービスなど、一部のシナリオでは、環境名と正確に一致する環境ファイル名セグメントを使用することが重要です。 たとえば、Staging 環境には大文字 "S" でファイル名 appsettings.Staging.json を使用します。 推奨される規則については、「ASP.NET Core Blazor 環境」の冒頭の解説を参照してください。

アプリによって登録されたその他の構成プロバイダーで構成を指定することもできますが、すべてのプロバイダーやプロバイダーの機能が適しているわけではありません。

  • Azure Key Vault 構成プロバイダー: クライアント シークレットのシナリオでは、このプロバイダーはマネージド ID およびアプリケーション ID (クライアント ID) に対してはサポートされていません。 クライアント シークレットを使用したアプリケーション ID は、ASP.NET Core アプリ、特にクライアント側のアプリでは推奨されません。これは、クライアント シークレットを Azure Key Vault サービスにアクセスするためにクライアント側ではセキュリティで保護できないためです。
  • Azure アプリ構成プロバイダー: このプロバイダーはクライアント側のアプリに適していません。これは、Azure 内のサーバー上で実行されないためです。

構成プロバイダーについて詳しくは、「ASP.NET Core での構成」を参照してください。

警告

構成ファイルと設定ファイルはクライアント上のユーザーに表示され、ユーザーがデータを改ざんする可能性があります。 アプリのシークレット、資格情報、その他の機微なデータをアプリの構成またはファイルに格納しないでください。

アプリ設定の構成

アプリ設定ファイルの構成は既定で読み込まれます。 次の例では、UI 構成値がアプリ設定ファイルに格納され、Blazor フレームワークによって自動的に読み込まれます。 その値はコンポーネントによって読み取られます。

wwwroot/appsettings.json:

{
    "h1FontSize": "50px"
}

構成データにアクセスするために、コンポーネントに IConfiguration インスタンスを挿入します。

ConfigExample.razor:

@page "/config-example"
@inject IConfiguration Configuration

<PageTitle>Configuration</PageTitle>

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example (50px)
</h1>
@page "/config-example"
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>
@page "/config-example"
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>
@page "/config-example"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>
@page "/config-example"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1 style="font-size:@Configuration["h1FontSize"]">
    Configuration example
</h1>

クライアントのセキュリティ制限により、アプリ構成の設定ファイルなどのファイルへのユーザー コードからの直接アクセスが防止されます。 appsettings.json/appsettings.{ENVIRONMENT}.json に加えて構成ファイルを wwwroot フォルダーから構成に読み取るには、HttpClient を使用します。

警告

構成ファイルと設定ファイルはクライアント上のユーザーに表示され、ユーザーがデータを改ざんする可能性があります。 アプリのシークレット、資格情報、その他の機微なデータをアプリの構成またはファイルに格納しないでください。

次の例では、構成ファイル (cars.json) をアプリの構成に読み取ります。

wwwroot/cars.json:

{
    "size": "tiny"
}

Program ファイルに Microsoft.Extensions.Configuration の名前空間を追加します。

using Microsoft.Extensions.Configuration;

クライアントを使用してファイルを読み取るように、既存の HttpClient サービス登録を変更します。

var http = new HttpClient()
{
    BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
};

builder.Services.AddScoped(sp => http);

using var response = await http.GetAsync("cars.json");
using var stream = await response.Content.ReadAsStreamAsync();

builder.Configuration.AddJsonStream(stream);

上記の例では、ベース アドレスの設定に builder.HostEnvironment.BaseAddress (IWebAssemblyHostEnvironment.BaseAddress) を使っています。これを使って、アプリのベース アドレス (通常は、ホスト ページの <base> タグの href 値に由来します) を取得できます。

メモリ構成のソース

次の例では、Program ファイルの MemoryConfigurationSource を使用して追加の構成を指定します。

Program ファイルに Microsoft.Extensions.Configuration.Memory の名前空間を追加します。

using Microsoft.Extensions.Configuration.Memory;

Program ファイルで次の操作を行います。

var vehicleData = new Dictionary<string, string?>()
{
    { "color", "blue" },
    { "type", "car" },
    { "wheels:count", "3" },
    { "wheels:brand", "Blazin" },
    { "wheels:brand:type", "rally" },
    { "wheels:year", "2008" },
};

var memoryConfig = new MemoryConfigurationSource { InitialData = vehicleData };

builder.Configuration.Add(memoryConfig);

構成データにアクセスするために、コンポーネントに IConfiguration インスタンスを挿入します。

MemoryConfig.razor:

@page "/memory-config"
@inject IConfiguration Configuration

<PageTitle>Memory Configuration</PageTitle>

<h1>Memory Configuration Example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>
@page "/memory-config"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration

<h1>Memory configuration example</h1>

<h2>General specifications</h2>

<ul>
    <li>Color: @Configuration["color"]</li>
    <li>Type: @Configuration["type"]</li>
</ul>

<h2>Wheels</h2>

<ul>
    <li>Count: @Configuration["wheels:count"]</li>
    <li>Brand: @Configuration["wheels:brand"]</li>
    <li>Type: @Configuration["wheels:brand:type"]</li>
    <li>Year: @Configuration["wheels:year"]</li>
</ul>

IConfiguration.GetSectionで C# コード内の構成セクションを取得します。 次の例では、前の例の構成の wheels セクションを取得します。

@code {
    protected override void OnInitialized()
    {
        var wheelsSection = Configuration.GetSection("wheels");

        ...
    }
}

認証の構成

アプリ設定ファイルで認証構成を指定します。

wwwroot/appsettings.json:

{
  "Local": {
    "Authority": "{AUTHORITY}",
    "ClientId": "{CLIENT ID}"
  }
}

Program ファイルで ConfigurationBinder.Bind を使用して、Identity プロバイダーの構成を読み込みます。 次の例では、OIDC プロバイダーの構成を読み込みます。

builder.Services.AddOidcAuthentication(options =>
    builder.Configuration.Bind("Local", options.ProviderOptions));

ログの構成

このセクションは、wwwroot フォルダー内のアプリ設定ファイルを使用してログを構成するアプリに適用されます。

アプリに Microsoft.Extensions.Logging.Configuration パッケージを追加します。

Note

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

アプリ設定ファイルで、ログ構成を指定します。 ログ構成は Program ファイルに読み込まれます。

wwwroot/appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Program ファイルで次の操作を行います。

builder.Logging.AddConfiguration(
    builder.Configuration.GetSection("Logging"));

ホスト ビルダーの構成

Program ファイルの WebAssemblyHostBuilder.Configuration からホスト ビルダーの構成を読み取ります。

var hostname = builder.Configuration["HostName"];

キャッシュされた構成

構成ファイルは、オフラインで使用できるようにキャッシュされます。 プログレッシブ Web アプリケーション (PWA) では、新しい展開を作成するときにのみ構成ファイルを更新できます。 次の理由により、展開間で構成ファイルを編集しても意味がありません。

  • ユーザーには、引き続き使用するファイルのキャッシュされたバージョンがあります。
  • PWA の service-worker.jsservice-worker-assets.js のファイルは、コンパイル時に再構築される必要があります。これにより、ユーザーの次回のオンライン アクセス時に、アプリが再展開されたことが通知されます。

PWA によるバックグラウンド更新の処理方法について詳しくは、「ASP.NET Core Blazor プログレッシブ Web アプリケーション (PWA)」をご覧ください。

オプションの構成

オプションの構成では、Microsoft.Extensions.Options.ConfigurationExtensions NuGet パッケージに対するパッケージ参照を追加する必要があります。

メモ

.NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

例:

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

ASP.NET Core オプションのすべての機能が、Razor コンポーネントでサポートされているわけではありません。 たとえば、IOptionsSnapshot<TOptions>IOptionsMonitor<TOptions> の構成はサポートされていますが、これらのインターフェイスのオプション値の再計算は、新しいブラウザー タブでアプリを要求するか、ブラウザーの再読み込みボタンを選択することによるアプリの再読み込み以外では、サポートされません。 基になる構成が変更されたとき、StateHasChanged を呼び出すだけでは、スナップショットまたは監視対象のオプション値は更新されません。