ASP.NET Core Blazor のホストと展開
注意
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 9 バージョンを参照してください。
この記事では、Blazor アプリをホストおよび展開する方法について説明します。
アプリの発行
アプリは、リリース構成での展開のために発行されます。
Note
Server プロジェクトからホステッド Blazor WebAssembly ソリューションを発行します。
- [ビルド] メニューから 「{APPLICATION} を発行する] コマンドを選択します。
{APPLICATION}
プレースホルダーはアプリの名前です。 - [publish target]\(発行先\) を選択します。 ローカルに発行するには、[フォルダー] を選択します。
- [フォルダーの選択] フィールド内で既定の場所を受け入れるか、または別の場所を指定します。
Publish
ボタンを選択します。
アプリを発行すると、プロジェクトの依存関係の復元がトリガーされ、展開されるアセットを作成する前にプロジェクトがビルドされます。 ビルド プロセスの一環として、アプリのダウンロード サイズを縮小し読み込み時間を短縮するため、未使用のメソッドおよびアセンブリが削除されます。
発行場所:
- Blazor Web App: アプリは
/bin/Release/{TARGET FRAMEWORK}/publish
フォルダーに発行されます。publish
フォルダーの内容をホストに展開します。 - Blazor WebAssembly: アプリは
bin\Release\net8.0\browser-wasm\publish\
フォルダーに発行されます。 アプリを静的サイトとして展開するには、wwwroot
フォルダーの内容を静的サイトのホストにコピーします。
- Blazor Server: アプリは
/bin/Release/{TARGET FRAMEWORK}/publish
フォルダーに発行されます。publish
フォルダーの内容をホストに展開します。 - Blazor WebAssembly
- スタンドアロン: アプリは、アプリの発行に使用される SDK のバージョンに応じて、
/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot
またはbin\Release\{TARGET FRAMEWORK}\browser-wasm\publish
フォルダーに発行されます。 アプリを静的サイトとして展開するには、wwwroot
フォルダーの内容を静的サイトのホストにコピーします。 - ホステッド: クライアントの Blazor WebAssembly アプリは、クライアント アプリの他の静的な Web アセットと共に、サーバー アプリの
/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot
フォルダーに発行されます。publish
フォルダーの内容をホストに展開します。
- スタンドアロン: アプリは、アプリの発行に使用される SDK のバージョンに応じて、
上記のパスの {TARGET FRAMEWORK}
は、ターゲット フレームワーク (たとえば、net8.0
) です。
IIS
IIS で Blazor アプリをホストするには、次のリソースを参照してください。
- IIS のホスティング
- ASP.NET Core サーバー側 Blazor アプリのホストと展開: Windows OS および Azure App Service を実行する Azure 仮想マシン (VM) を備えた IIS を含む、IIS 上で実行されるサーバー アプリ。
- ASP.NET Core のホストと展開Blazor WebAssembly: 静的サイト ホスティング、カスタム
web.config
ファイル、URL 書き換え、サブアプリ、圧縮、Azure Storage 静的ファイル ホスティングなど、IIS でホストされる Blazor WebAssembly アプリに関する追加のガイダンスが含まれています。 - IIS サブアプリケーションのホスト
- アプリを発行する前に、 Blazor アプリの「 アプリのベース パス」セクションのガイダンスに従ってください。 この例では、アプリのベース パス
/CoolApp
を使い、アプリ設定または他の構成プロバイダーからベース パスを取得する方法を示します。 - 「高度な構成」にあるサブアプリケーションの構成に関するガイダンスに従ってください。 ルート サイトの下にあるサブアプリのフォルダー パスがサブアプリの仮想パスになります。
/CoolApp
のアプリ ベース パスの場合、Blazor アプリはルート サイトの下のCoolApp
という名前のフォルダーに配置され、サブアプリは/CoolApp
の仮想パスを使用します。
- アプリを発行する前に、 Blazor アプリの「 アプリのベース パス」セクションのガイダンスに従ってください。 この例では、アプリのベース パス
Blazor アプリを含め、ASP.NET Core アプリ間のアプリ プールの共有はサポートされていません。 IIS でホストする場合は、アプリごとに 1 つのアプリ プールを使い、複数のアプリをホストするために IIS の仮想ディレクトリを使用しないようにしてください。
"1 つ" のアプリ プールに対して、ASP.NET Core アプリによってホストされる 1 つ以上の Blazor WebAssembly アプリ (ホステッド Blazor WebAssembly ソリューションと呼ばれます) がサポートされます。 ただし、1 つのアプリ プールを複数のホステッド Blazor WebAssembly ソリューションに割り当てること、またはサブアプリのホスティング シナリオで割り当てることは推奨されず、またサポートもされません。
ソリューションの詳細については、「ASP.NET Core Blazor 用のツール」を参照してください。
アプリのベース パス
アプリのベース パスとは、アプリのルート URL パスのことです。 Blazor アプリでルーティングが成功するためには、既定のアプリ ベース パス /
にないルート URL パスに対するフレームワーク構成が必要です。
次の ASP.NET Core アプリと Blazor サブアプリについて考えてみましょう。
- ASP.NET Core アプリは
MyApp
と命名します。- このアプリは、物理的に
d:/MyApp
に存在します。 - 要求は、
https://www.contoso.com/{MYAPP RESOURCE}
で受信されます。
- このアプリは、物理的に
CoolApp
という名前の Blazor アプリはMyApp
のサブアプリです。- このサブアプリは、物理的に
d:/MyApp/CoolApp
に存在します。 - 要求は、
https://www.contoso.com/CoolApp/{COOLAPP RESOURCE}
で受信されます。
- このサブアプリは、物理的に
CoolApp
に対して構成を追加指定しない場合、このシナリオではサブ アプリにはそれがサーバー上のどこの場所にあるかわかりません。 たとえば、相対 URL パス /CoolApp/
にあることがわからない場合、アプリはそのリソースに対する正しい相対 URL を作成できません。 このシナリオは、アプリがルート URL パスでホストされていない場合、さまざまなホスティングおよびリバース プロキシのシナリオでも適用されます。
背景
アンカー タグの宛先 (href
) は、次の 2 つのエンドポイントのいずれかで構成できます。
絶対位置。スキーム (省略した場合はページのスキームが既定値になります)、ホスト、ポート、およびパスまたはスラッシュ (
/
) の後に続くパスが含まれます。例:
https://example.com/a/b/c
または/a/b/c
相対位置。パスのみが含まれており、スラッシュ (
/
) で始まりません。 これらは、現在のドキュメント URL または<base>
タグの値 (指定されている場合) を基準にして解決されます。例:
a/b/c
構成されたアプリのベース パスの末尾にスラッシュ (/
) が存在することは、アプリの URL のベース パスを計算する上で重要です。 たとえば、 https://example.com/a
のベース パスは https://example.com/
であり、末尾にスラッシュがある https://example.com/a/
のベース パスは https://example.com/a
となります。
ASP.NET Core アプリの Blazor に関連するリンクには、次の 3 つのソースがあります。
- 通常、Razor コンポーネント (
.razor
) の URL は相対的です。 - Blazor スクリプト (
blazor.*.js
) などのスクリプトの URL。ドキュメントに対して相対的です。
_Host.cshtml
ファイル (Blazor Server) に手動で記述された URL。異なるドキュメント内でレンダリングする場合は、常に絶対 URL にする必要があります。- 通常、Razor コンポーネント (
.razor
) の URL は相対的です。 - Blazor スクリプト (
blazor.*.js
) などのスクリプトの URL。ドキュメントに対して相対的です。
異なるドキュメント (/Admin/B/C/
や /Admin/D/E/
など) から Blazor アプリをレンダリングする場合は、アプリのベース パスを考慮する必要があります。ベース パスが異なると、アプリが各ドキュメントでレンダリングされる際にリソースが間違った URL からフェッチされることになります。
相対リンクを正しく解決するという課題に対処するには、次の 2 つの方法があります。
- ルートとしてレンダリングされたドキュメントを使用して、リソースを動的にマップします。
- ドキュメントの一貫したベース パスを設定し、そのベース パスの下にリソースをマップします。
最初のオプションはドキュメントごとにナビゲーションが異なるため、より複雑であり、最も一般的なアプローチではありません。 ページ /Something/Else
をレンダリングする例を次に示します。
/Admin/B/C/
の下にレンダリングすると、ページは/Admin/B/C/Something/Else
のパスでレンダリングされます。/Admin/D/E/
の下にレンダリングすると、ページは同じパスの/Admin/B/C/Something/Else
でレンダリングされます。
最初のアプローチでは、ルーティングによって IDynamicEndpointMetadata と MatcherPolicy が提供されます。これらは組み合わせることで、実行時にリクエストのルーティング方法を決定する完全に動的なソリューションを実装するための基礎となります。
通常の方法である 2 番目のオプションでは、アプリはドキュメント内のベース パスを設定し、サーバー エンドポイントをベースの下のパスにマップします。 次のガイダンスでは、このアプローチを採用しています。
サーバー側 Blazor
Program
ファイル内の MapBlazorHub へのパスを渡して、サーバー側 Blazor アプリの SignalR ハブをマップします。
app.MapBlazorHub("base/path");
MapBlazorHub を使用する利点は、具体的なパスだけでなく、"{tenant}"
などのパターンをマップできることです。
また、アプリが分岐ミドルウェア パイプラインを持つ仮想フォルダー内にある場合に SignalR ハブをマップすることもできます。 次の例では、/base/path/
への要求は Blazor の SignalR ハブによって処理されます。
app.Map("/base/path/", subapp => {
subapp.UsePathBase("/base/path/");
subapp.UseRouting();
subapp.UseEndpoints(endpoints => endpoints.MapBlazorHub());
});
「アプリのベース パスを構成する」セクションのガイダンスに従って、<base>
タグを構成します。
ホステッド Blazor WebAssembly
ホストされている Blazor WebAssembly アプリの場合:
- Server プロジェクト (
Program.cs
) の場合:- UseBlazorFrameworkFiles のパスを調整します (たとえば、
app.UseBlazorFrameworkFiles("/base/path");
)。 - UseStaticFiles への呼び出しを構成します (たとえば、
app.UseStaticFiles("/base/path");
)。
- UseBlazorFrameworkFiles のパスを調整します (たとえば、
- Client プロジェクトの場合:
- 静的 Web アセットを提供するためのパスと一致するように、プロジェクト ファイル内の
<StaticWebAssetBasePath>
を構成します (たとえば、<StaticWebAssetBasePath>base/path</StaticWebAssetBasePath>
)。 - 「アプリのベース パスを構成する」セクションのガイダンスに従って、
<base>
タグを構成します。
- 静的 Web アセットを提供するためのパスと一致するように、プロジェクト ファイル内の
ホストされた Blazor WebAssembly ソリューションで複数の Blazor WebAssembly アプリをホストする例については、「複数のホストされた ASP.NET Core Blazor WebAssembly アプリ」を参照してください。このページでは、複数の Blazor WebAssembly クライアント アプリのドメイン/ポート ホスティングとサブパス ホスティングに関するアプローチについて説明しています。
スタンドアロン Blazor WebAssembly
スタンドアロン Blazor WebAssembly アプリの場合は、「アプリのベース パスを構成する」セクションのガイダンスに従って、<base>
タグのみを構成します。
アプリのベース パスを構成する
Blazor アプリのベース パスのhttps://www.contoso.com/CoolApp/
の構成を提供するには、app ベース パス (<base>
) (相対ルート パスとも呼ばれます) を設定します。
アプリのベース パスを構成することにより、ルート ディレクトリに存在しないコンポーネントでアプリのルート パスへの相対 URL を構築できます。 ディレクトリ構造の別のレベルに存在するコンポーネントが、アプリ内のさまざまな場所にある他のリソースに対するリンクを構築できます。 アプリのベース パスは、リンクの href
ターゲットがアプリのベース パス URI 空間内にある、選択されたハイパーリンクの阻止にも使用されます。 内部のナビゲーションは、Router コンポーネントによって処理されます。
<link>
要素のhref
属性など、URL である属性値を持つ要素の前に、<base>
タグを<head>
マークアップ ( <head>
コンテンツの割り当て) に配置します。
多くのホスティング シナリオでは、アプリへの相対 URL パスは、アプリのルートです。 このような既定のケースでは、アプリの相対 URL ベース パスは、/
であり、<head>
コンテンツで <base href="/" />
として構成されます。
多くのホスティング シナリオでは、アプリへの相対 URL パスは、アプリのルートです。 これらの既定のケースでは、アプリの相対 URL のベース パスは、<head>
コンテンツ で次のようになります。
- Blazor Server:
~/
を<base href="~/" />
として構成。 - Blazor WebAssembly:
/
を<base href="/" />
として構成。
Note
GitHub ページと IIS サブアプリなど、一部のホスティング シナリオの場合、アプリのベースパスは、アプリへのサーバーの相対 URL パスに設定する必要があります。
サーバー側 Blazor アプリでは、次の "いずれか" の方法を使用してください。
オプション 1:
<base>
タグを使用して、アプリのベース パスを設定する (<head>
コンテンツの場所)。<base href="/CoolApp/">
末尾にスラッシュが必要です。
オプション 2: WebApplicationBuilder がビルド (
builder.Build()
) された直後に、アプリの要求処理パイプライン (Program.cs
) で "最初に" UsePathBase を呼び出して、要求パスと対話する以降のミドルウェアのベース パスを構成します。app.UsePathBase("/CoolApp");
UsePathBase の呼び出しは、Blazor Server アプリをローカル環境でも実行したい場合に推奨されます。 たとえば、
Properties/launchSettings.json
に起動 URL を指定します。"launchUrl": "https://localhost:{PORT}/CoolApp",
前の例の
{PORT}
プレース ホルダーは、applicationUrl
構成パス内のセキュリティで保護されたポートと一致するポートです。 次の例では、ポート 7279 におけるアプリの完全起動プロファイルを示しています。"BlazorSample": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "https://localhost:7279;http://localhost:5279", "launchUrl": "https://localhost:7279/CoolApp", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }
launchSettings.json
ファイルの詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。 Blazor アプリのベース パスとホスティングの詳細については、 「Blazor MVC 統合の<base href="/" />
またはベース タグの代替方法 (dotnet/aspnetcore #43191)」を参照してください。
スタンドアロン Blazor WebAssembly (
wwwroot/index.html
):<base href="/CoolApp/">
末尾にスラッシュが必要です。
ホステッド Blazor WebAssembly (Client プロジェクト、
wwwroot/index.html
):<base href="/CoolApp/">
末尾にスラッシュが必要です。
Server プロジェクトで、WebApplicationBuilder がビルド (
builder.Build()
) された直後に、アプリの要求処理パイプライン (Program.cs
) で "最初に" UsePathBase を呼び出して、要求パスと対話する以降のミドルウェアのベース パスを構成します。app.UsePathBase("/CoolApp");
Note
WebApplication を使用する場合 (ASP.NET Core 5.0 から 6.0 への移行に関する記事を参照) は、UsePathBase の後に app.UseRouting
を呼び出して、ルーティング ミドルウェアがルートを照合する前に変更されたパスを確認できるようにする必要があります。 そうしない場合、ミドルウェアの順序とルーティングに関する記事で説明されているように、ルートはパスが書き直される前に UsePathBase によって照合されます。
アプリ全体のリンクの先頭にフォワード スラッシュを付けないでください。 パス セグメント区切り記号を使わないか、ドットスラッシュ (./
) による相対パス表記を使ってください。
<a href="/account">
正しくない: <a href="account">
正しい: <a href="./account">
正しい:
HttpClient
サービスを使用する Blazor WebAssembly Web API 要求では、JSON ヘルパー (HttpClientJsonExtensions) によって URL の先頭にフォワード スラッシュ (/
) が付けられていないことを確認します。
var rsp = await client.GetFromJsonAsync("/api/Account");
正しくない: var rsp = await client.GetFromJsonAsync("api/Account");
正しい:
Navigation Manager の相対リンクの先頭にフォワード スラッシュを付けないでください。 パスのセグメント区切り記号を使わないか、ドットスラッシュ (./
) による相対パス表記を使ってください (Navigation
は挿入された NavigationManager です):
Navigation.NavigateTo("/other");
正しくない: Navigation.NavigateTo("other");
正しい: Navigation.NavigateTo("./other");
正しい:
Azure または IIS ホスティングの一般的な構成では、通常、追加の構成は必要ありません。 IIS 以外のホスティングおよびリバース プロキシ ホスティングの一部のシナリオでは、追加の静的ファイル ミドルウェア構成が必要になる場合があります。
- 静的ファイルを正しく処理する場合 (たとえば、
app.UseStaticFiles("/CoolApp");
)。 - Blazor スクリプトを提供する場合 (
_framework/blazor.*.js
)。 詳しくは、「ASP.NET Core Blazor の静的ファイル」をご覧ください。
ルート以外の相対 URL パスが構成されている Blazor WebAssembly アプリの場合 (例: <base href="/CoolApp/">
)、そのアプリは "ローカルで実行されると" 自身のリソースを見つけることができません。 ローカルでの開発およびテスト中は、実行時の <base>
タグの href
値と一致するパス ベース引数を指定することで、この問題を克服することができます。 末尾にはスラッシュを含めないでください。 アプリをローカルで実行する際にパス ベース引数を渡すには、以下のようにアプリのディレクトリから --pathbase
オプションを指定して dotnet watch
(または dotnet run
) コマンドを実行します。
dotnet watch --pathbase=/{RELATIVE URL PATH (no trailing slash)}
相対 URL パスが /CoolApp/
(<base href="/CoolApp/">
) の Blazor WebAssembly アプリについては、このコマンドは次のようになります。
dotnet watch --pathbase=/CoolApp
dotnet watch
(または dotnet run
) を使用して手動で指定するのではなく、pathbase
を自動的に指定するようにアプリの起動プロファイルを構成したい場合は、Properties/launchSettings.json
で commandLineArgs
プロパティを設定します。 次も、起動 URL (launchUrl
) を構成します。
"commandLineArgs": "--pathbase=/{RELATIVE URL PATH (no trailing slash)}",
"launchUrl": "{RELATIVE URL PATH (no trailing slash)}",
例のように CoolApp
を使用します。
"commandLineArgs": "--pathbase=/CoolApp",
"launchUrl": "CoolApp",
--pathbase
オプションを指定した dotnet watch
(または dotnet run
)、あるいはベース パスを設定する起動プロファイル構成を使用すると、Blazor WebAssembly アプリは http://localhost:port/CoolApp
でローカルに応答します。
launchSettings.json
ファイルの詳細については、「ASP.NET Core で複数の環境を使用する」を参照してください。 Blazor アプリのベース パスとホスティングの詳細については、 「Blazor MVC 統合の <base href="/" />
またはベース タグの代替方法 (dotnet/aspnetcore #43191)」を参照してください。
構成からアプリのベース パスを取得する
次のガイダンスでは、さまざまな環境のアプリ設定ファイルから <base>
タグのパスを取得する方法について説明します。
アプリ設定ファイルをアプリに追加します。 次の例は、Staging
環境 (appsettings.Staging.json
) の場合です。
{
"AppBasePath": "staging/"
}
サーバー側の Blazor アプリで、<head>
コンテンツの構成からベース パスを読み込みます。
@inject IConfiguration Config
...
<head>
...
<base href="/@(Config.GetValue<string>("AppBasePath"))" />
...
</head>
または、サーバー側アプリは、UsePathBase の構成から値を取得できます。 WebApplicationBuilder が構築された (builder.Build()
) 直後に、次のコードをアプリの要求処理パイプライン (Program.cs
) の最初に配置します。 次の例では、構成キー AppBasePath
を使います。
app.UsePathBase($"/{app.Configuration.GetValue<string>("AppBasePath")}");
クライアントサイド Blazor WebAssembly アプリ内は以下のようになっています。:
wwwroot/index.html
から<base>
タグを削除します。- <base href="..." />
App
コンポーネント (App.razor
) のHeadContent
コンポーネントを介してアプリのベース パスを指定します。@inject IConfiguration Config ... <HeadContent> <base href="/@(Config.GetValue<string>("AppBasePath"))" /> </HeadContent>
非ステージング環境など、読み込む構成値がない場合、上記の href
はルート パス /
に解決されます。
このセクションの例では、アプリ設定からアプリのベース パスを指定することに焦点を当てていますが、IConfiguration からパスを読み取るアプローチは、どの構成プロバイダーでも有効です。 詳細については、次のリソースを参照してください。
Blazor ServerMapFallbackToPage
構成
"このセクションは Blazor Server アプリにのみ適用されます。 " MapFallbackToPage は、Blazor Web App および Blazor WebAssembly アプリではサポートされていません。
アプリでカスタム リソースと Razor コンポーネントを含む区分が別に必要なシナリオでは、次の操作を行います。
アプリの
Pages
フォルダー内に、リソースを保持するためのフォルダーを作成します。 たとえば、アプリの管理者セクションは、Admin
という名前の新しいフォルダー内に作成されます (Pages/Admin
)。その区分のルート ページ (
_Host.cshtml
) を作成します。 たとえば、アプリのメイン ルート ページ (Pages/_Host.cshtml
) からPages/Admin/_Host.cshtml
ファイルを作成します。 Admin_Host
ページには、@page
ディレクティブを指定しないでください。区分のフォルダーにレイアウトを追加します (例:
Pages/Admin/_Layout.razor
)。 別の区分のレイアウトで、<base>
タグhref
を設定して、その区分のフォルダーと一致するようします (例:<base href="/Admin/" />
)。 デモンストレーションの目的で、ページ内の静的リソースに~/
を追加します。 次に例を示します。~/css/bootstrap/bootstrap.min.css
~/css/site.css
~/BlazorSample.styles.css
(サンプル アプリの名前空間はBlazorSample
です)。~/_framework/blazor.server.js
(Blazor スクリプト)
区分に独自の静的アセット フォルダーが必要な場合は、該当するフォルダーを追加し、その場所を
Program.cs
内の静的ファイル ミドルウェアに指定します (例:app.UseStaticFiles("/Admin/wwwroot")
)。Razor コンポーネントが区分のフォルダーに追加されます。 少なくとも、区分の正しい
@page
ディレクティブを使用してIndex
コンポーネントを区分フォルダーに追加します。 たとえば、アプリの既定のPages/Index.razor
のファイルに基づいてPages/Admin/Index.razor
ファイルを追加します。 ファイルの先頭にルート テンプレートとして Admin 区分を指定します (@page "/admin"
)。 必要に応じて追加のコンポーネントを追加します。 たとえば、@page "/admin/component1
の@page
ディレクティブとルート テンプレートを使用したPages/Admin/Component1.razor
。Program.cs
では、_Host
ページへのフォールバック ルート ページ パスの直前に、区分の要求パスに対して MapFallbackToPage を呼び出します。... app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("~/Admin/{*clientroutes:nonfile}", "/Admin/_Host"); app.MapFallbackToPage("/_Host"); app.Run();
複数のBlazor WebAssembly アプリをホストする
ホステッド Blazor ソリューションで複数の Blazor WebAssembly アプリをホストする方法の詳細については、「複数のホステッド ASP.NET Core Blazor WebAssembly アプリ」を参照してください。
展開
展開のガイダンスについては、次のトピックを参照してください。
ASP.NET Core