ASP.NET Core Blazor の環境

注意

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

この記事では、Blazor アプリで環境の構成と読み取りを行う方法について説明します。

この記事では、アプリ コードが実行される場所を区別するために、サーバー/サーバー側クライアント/クライアント側という用語が使用されます。

  • サーバー/サーバー側: Blazor Web アプリの対話型サーバー側レンダリング (対話型 SSR)。
  • クライアント/クライアント側
    • Blazor Web アプリのクライアント側レンダリング (CSR)。
    • Blazor WebAssembly アプリ。

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

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

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

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

  • サーバー/サーバー側
    • ホスト型 Blazor WebAssembly アプリの Server プロジェクト。
    • Blazor Server アプリ。
  • クライアント/クライアント側
    • ホスト型 Blazor WebAssembly アプリの Client プロジェクト。
    • Blazor WebAssembly アプリ。

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

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

アプリをローカルで実行する場合、環境は既定で Development になります。 アプリが発行されると、環境は既定で Production になります。

次の規則に従うことをお勧めします。

  • ローカル開発には常に "Development" という環境名を使います。 これは、ASP.NET Core フレームワークでは、アプリのローカル開発実行用にアプリとツールを構成するときに、そのとおりの名前が想定されるためです。

  • テスト、ステージング、運用の各環境の場合は、常にアプリを発行してデプロイします。 発行されるアプリ用の環境には任意の名前付け方式を使用できますが、アプリ設定のファイル名の環境セグメント部分は、大文字と小文字の使い分けが常に環境名と完全に一致するようにします。 ステージング環境の場合は、環境名として "Staging" (大文字の "S") を使い、アプリ設定ファイルに一致する名前を付けます (appsettings.Staging.json)。 運用環境の場合は、環境名として "Production" (大文字の "P") を使い、アプリ設定ファイルに一致する名前を付けます (appsettings.Production.json)。

環境を設定する

環境は、次のいずれかの方法を使用して設定されます。

Blazor Web アプリのクライアントでは、blazor-environment という名前のヘッダーを使用してブラウザーに環境を伝えるミドルウェアを介して、サーバーからの環境に決定されます。 クライアント側の Program ファイルで WebAssemblyHost が作成されるときに (WebAssemblyHostBuilder.CreateDefault)、ヘッダーによって環境が設定されます。

環境は、次のいずれかの方法を使用して設定されます。

Blazor Web アプリのクライアント、またはホストされる Blazor WebAssembly アプリのクライアントでは、blazor-environment という名前のヘッダーを使用してブラウザーに環境を伝えるミドルウェアを介して、サーバーからの環境に決定されます。 クライアント側の Program ファイルで WebAssemblyHost が作成されるときに (WebAssemblyHostBuilder.CreateDefault)、ヘッダーによって環境が設定されます。

ローカルで実行されるスタンドアロンの Blazor WebAssembly アプリの場合、開発サーバーによって blazor-environment ヘッダーが追加されます。

開発時にローカルで実行されるアプリの場合、アプリの環境は既定で Development になります。 アプリが発行されると、アプリの環境は既定で Production になります。

ASP.NET Core アプリの一般的なガイダンスについては、「ASP.NET Core で複数の環境を使用する」を参照してください。 開発中およびテスト中 (たとえば、Staging) の Development 環境以外の環境における静的ファイルでのサーバー側のアプリ構成については、ASP.NET Core Blazor 静的ファイルに関するページを参照してください。

Blazor のスタートアップ構成を使ってクライアント側環境を設定する

次の例では、ホスト名に localhost が含まれる場合に Staging 環境で Blazor を開始しています。 それ以外の場合、環境は既定値に設定されます。

Blazor Web アプリ:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  if (window.location.hostname.includes("localhost")) {
    Blazor.start({
      webAssembly: {
        environment: "Staging"
      }
    });
  } else {
    Blazor.start();
  }
</script>

前の例の {BLAZOR SCRIPT} プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。

Note

Blazor.start 構成で webAssembly>environment プロパティを設定する Blazor Web アプリの場合は、サーバー側の環境を environment プロパティで設定される環境と一致させることをお勧めします。 そうしないと、サーバーでのプリレンダリングがクライアントでのレンダリングとは異なる環境で行われ、結果としてどのような効果になるかわかりません。 Blazor Web アプリ用の環境の設定に関する一般的なガイダンスについては、「ASP.NET Core で複数の環境を使用する」をご覧ください。

スタンドアロン Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  if (window.location.hostname.includes("localhost")) {
    Blazor.start({
      environment: "Staging"
    });
  } else {
    Blazor.start();
  }
</script>

前の例の {BLAZOR SCRIPT} プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。

environment プロパティを使用すると、blazor-environment ヘッダーによって設定された環境がオーバーライドされます。

上の方法を使うと、blazor-environment ヘッダーの値を変えずにクライアントの環境が設定され、グローバルな対話型 WebAssembly レンダリングが採用されている Blazor Web アプリ用の起動環境のサーバー プロジェクトのコンソール ログも変更されません。

スタンドアロン Blazor WebAssembly プロジェクトまたは Blazor Web アプリの .Client プロジェクトのコンソールに環境をログするには、Program ファイルの、WebAssemblyHostBuilder.CreateDefault を使って WebAssemblyHost を作成している箇所より後で、プロジェクトをビルドして実行している行 (await builder.Build().RunAsync();) より前に、次の C# コードを配置します。

Console.WriteLine(
    $"Client Hosting Environment: {builder.HostEnvironment.Environment}");

Blazor の起動の詳細については、「ASP.NET Core Blazor の起動」をご覧ください。

ヘッダーを使用してクライアント側環境を設定する

Blazor WebAssembly アプリでは、blazor-environment ヘッダーを使って環境を設定できます。

次の IIS の例では、発行された web.config ファイルにカスタム ヘッダー (blazor-environment) が追加されます。 web.config ファイルは bin/Release/{TARGET FRAMEWORK}/publish フォルダー内にあります。プレースホルダー {TARGET FRAMEWORK} はターゲット フレームワークです。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>

    ...

    <httpProtocol>
      <customHeaders>
        <add name="blazor-environment" value="Staging" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

Note

アプリが publish フォルダーに発行されたときに上書きされない IIS 用のカスタム web.config ファイルを使用するには、「ASP.NET Core Blazor WebAssembly のホストと展開」をご覧ください。

Blazor フレームワークではヘッダー名がすべて小文字 (blazor-environment) で発行されますが、ユーザーは大文字と小文字をどのように使い分けてもかまいません。 たとえば、各単語の先頭を大文字にしたヘッダー名 (Blazor-Environment) もサポートされます。

Azure App Service の環境を設定する

スタンドアロンの Blazor WebAssembly アプリの場合は、起動構成または blazor-environment ヘッダーを使って手動で環境を設定できます。

サーバー側アプリの場合は、Azure の ASPNETCORE_ENVIRONMENT アプリ設定を使って環境を設定します。

  1. "アプリ設定ファイル名内の環境セグメントの大文字と小文字が、その環境名の大文字と小文字と'完全に一致していることを確認します"。 たとえば、Staging 環境の一致するアプリ設定ファイル名は appsettings.Staging.json です。 ファイル名が appsettings.staging.json ("s" は小文字) の場合、ファイルは見つからず、ファイル内の設定は Staging 環境で使用されません。

  2. Visual Studio のデプロイの場合、アプリが正しいデプロイ スロットにデプロイされていることを確認します。 BlazorAzureAppSample という名前のアプリの場合、アプリは Staging デプロイ スロットにデプロイされます。

  3. 環境のデプロイ スロットについて、Azure portal で、ASPNETCORE_ENVIRONMENT アプリ設定を使用して環境を設定します。 BlazorAzureAppSample という名前のアプリの場合、ステージング App Service スロットには BlazorAzureAppSample/Staging という名前が付けられます。 Staging スロットの構成では、ASPNETCORE_ENVIRONMENT のアプリ設定を Staging の値で作成します。 設定に対して、デプロイ スロットの設定が有効になっています。

ブラウザーで要求された場合、BlazorAzureAppSample/Staging アプリは https://blazorazureappsample-staging.azurewebsites.netStaging 環境に読み込まれます。

アプリがブラウザーに読み込まれると、blazor.boot.json の応答ヘッダー コレクションでは、blazor-environment ヘッダー値が Staging であることが示されます。

appsettings.{ENVIRONMENT}.json ファイルのアプリ設定はアプリによって読み込まれます。ここで {ENVIRONMENT} プレースホルダーはアプリの環境です。 前の例では、appsettings.Staging.json ファイルの設定が読み込まれます。

Blazor WebAssembly アプリで環境を読み取る

IWebAssemblyHostEnvironment を挿入し、Environment プロパティを読み取ることで、コンポーネント内のアプリの環境を取得します。

ReadEnvironment.razor:

@page "/read-environment"
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IWebAssemblyHostEnvironment Env

<h1>Environment example</h1>

<p>Environment: @HostEnvironment.Environment</p>

Blazor Web アプリでクライアント側環境を読み取る

コンポーネントまたはアプリでプリレンダリングが無効になっていないとすると、.Client プロジェクト内のコンポーネントはサーバー上でプリレンダリングされます。 サーバーには IWebAssemblyHostEnvironment サービスが登録されていないため、サービスを挿入し、サーバーのプリレンダリングの間にサービスの実装のホスト環境拡張メソッドとプロパティを使うことはできません。 対話型 WebAssembly または対話型自動コンポーネントにサービスを挿入すると、次のランタイム エラーが発生します。

There is no registered service of type 'Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment'.

これに対処するには、サーバー上に IWebAssemblyHostEnvironment 用のカスタム サービスの実装を作成します。 サーバー プロジェクトに次のクラスを追加します。

ServerHostEnvironment.cs:

using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Components;

public class ServerHostEnvironment(IWebHostEnvironment env, NavigationManager nav) : 
    IWebAssemblyHostEnvironment
{
    public string Environment => env.EnvironmentName;
    public string BaseAddress => nav.BaseUri;
}

サーバー プロジェクトの Program ファイルで、サービスを登録します。

builder.Services.TryAddScoped<IWebAssemblyHostEnvironment, ServerHostEnvironment>();

ここまで済めば、IWebAssemblyHostEnvironment サービスを対話型 WebAssembly または対話型自動コンポーネントに挿入し、「Blazor WebAssembly アプリで環境を読み取る」セクションで示されているようにしてそれを使用できます。

前の例は、クライアント環境とは異なるサーバー環境を使用できることを示していますが、これは推奨されておらず、思いもよらない結果になる可能性があります。 Blazor Web アプリで環境を設定するときは、サーバーと .Client プロジェクトの環境を一致させるのが最善です。 テスト アプリでの次のシナリオについて考えてください。

  • Blazor.start を使って、Staging 環境でクライアント側 (webassembly) 環境プロパティを実装します。 例については、「起動構成を使用してクライアント側環境を設定する」セクションをご覧ください。
  • サーバー側の Properties/launchSettings.json ファイルは変更しないでください。 environmentVariables セクションの ASPNETCORE_ENVIRONMENT 環境変数は Development に設定されたままにします。

IWebAssemblyHostEnvironment.Environment プロパティの値の変更は UI で確認できます。

サーバーでプリレンダリングが行われると、コンポーネントは Development 環境でレンダリングされます。

Environment: Development

1 または 2 秒後にコンポーネントが再レンダリングされると、Blazor バンドルがダウンロードされて Blazor WebAssembly ランタイムがアクティブになった後、クライアントが Staging 環境で動作していることを反映するように値が変更されます。

Environment: Staging

前の例は、開発、テスト、運用のデプロイでクライアント環境と一致するようにサーバー環境を設定することをお勧めする理由を示しています。

詳しくは、Blazor のドキュメントの後の方にある "レンダリング モード" に関する記事の「プリレンダリング中にクライアント側サービスによる解決が失敗する」をご覧ください。

起動時にクライアント側環境を読み取る

起動時に、WebAssemblyHostBuilder によって IWebAssemblyHostEnvironmentHostEnvironment プロパティを介して公開されます。これにより、ホスト ビルダー コードで環境固有のロジックが有効になります。

Program ファイルで次のようになります。

if (builder.HostEnvironment.Environment == "Custom")
{
    ...
};

WebAssemblyHostEnvironmentExtensions を通じて提供された次の便利な拡張メソッドを使用すると、現在の環境で DevelopmentProductionStaging、およびカスタムの環境名を確認できます。

Program ファイルで次のようになります。

if (builder.HostEnvironment.IsStaging())
{
    ...
};

if (builder.HostEnvironment.IsEnvironment("Custom"))
{
    ...
};

IWebAssemblyHostEnvironment.BaseAddress プロパティは、NavigationManager サービスを利用できないときの起動時に使用できます。

その他の技術情報