ASP.NET Core Razor コンポーネントを ASP.NET Core アプリに統合する

この記事では、ASP.NET Core アプリの Razor コンポーネント統合シナリオについて説明します。

Razor コンポーネント統合

Razor コンポーネントは、Razor Pages、MVC、その他の種類の ASP.NET Core アプリに統合できます。 Razor コンポーネントは、カスタム HTML 要素として、ASP.NET Core に基づいていないアプリを含め、任意の Web アプリに統合することもできます。

プロジェクトの要件に応じて、次のセクションのガイダンスを使用します。

ASP.NET Core アプリに Blazor のサポートを追加する

このセクションでは、ASP.NET Core アプリへの Blazor のサポートの追加について説明します。

Note

このセクションの例では、アプリの名前と名前空間は BlazorSample です。

静的サーバー側レンダリング (静的 SSR) の追加

アプリに Components フォルダーを追加します。

_Imports コンポーネントで使用される名前空間用に次の Razor ファイルを追加してください。

Components/_Imports.razor:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components

名前空間プレースホルダー ({APP NAMESPACE}) をアプリの名前空間に変更します。 次に例を示します。

@using BlazorSample
@using BlazorSample.Components

アプリの Components フォルダーに配置されている Routes コンポーネント内のアプリに Blazor ルーター (<Router>Router) を追加します。

Components/Routes.razor:

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="routeData" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

RouteView コンポーネントの RouteView.DefaultLayout パラメーターを使用して、既定のレイアウトを指定できます。

<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />

詳しくは、「ASP.NET Core の Blazor レイアウト」を参照してください。

アプリに App コンポーネントを追加します。このコンポーネントはルート コンポーネントとして機能し、アプリが最初に読み込むコンポーネントとなります。

Components/App.razor:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="BlazorSample.styles.css" />
    <HeadOutlet />
</head>

<body>
    <Routes />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

前の例の <link> 要素については、スタイル シートのファイル名の BlazorSample をアプリのプロジェクト名と一致するように変更してください。 たとえば、ContosoApp という名前のプロジェクトでは、ContosoApp.styles.css というスタイルシート ファイル名が使用されます。

<link rel="stylesheet" href="ContosoApp.styles.css" />

ルーティング可能な Razor コンポーネントを保持する Pages フォルダーを Components フォルダーに追加してください。

次の Welcome コンポーネントを追加して、静的 SSR を示してください。

Components/Pages/Welcome.razor:

@page "/welcome"

<PageTitle>Welcome!</PageTitle>

<h1>Welcome to Blazor!</h1>

<p>@message</p>

@code {
    private string message = 
        "Hello from a Razor component and welcome to Blazor!";
}

ASP.NET Core プロジェクトの Program ファイルで、次の手順を実行してください。

  • プロジェクトのコンポーネントのファイルの先頭に using ステートメントを追加してください。

    using {APP NAMESPACE}.Components;
    

    上記の行では、{APP NAMESPACE} プレースホルダーをアプリの名前空間に変更します。 次に例を示します。

    using BlazorSample.Components;
    
  • Razor コンポーネント サービスを追加します (AddRazorComponents)。これは、偽造防止サービスも自動的に追加します (AddAntiforgery)。 builder.Build() を呼び出す行の前に次の行を追加してください。

    builder.Services.AddRazorComponents();
    
  • UseAntiforgery を使用して、要求処理パイプラインに偽造防止ミドルウェアを追加します。 UseRouting の呼び出しの後に UseAntiforgery が呼び出されます。 UseRoutingUseEndpoints の呼び出しがある場合、UseAntiforgery の呼び出しはそれらの間に置く必要があります。 UseAntiforgery の呼び出しは、UseAuthenticationUseAuthorization の呼び出しの後に置く必要があります。

    app.UseAntiforgery();
    
  • 既定のルート コンポーネント (最初に読み込まれるコンポーネント) として指定されている App コンポーネント (App.razor) を使って、アプリの要求処理パイプラインに MapRazorComponents を追加してください。 app.Run を呼び出す行の前に次のコードを配置してください。

    app.MapRazorComponents<App>();
    

アプリを実行すると、Welcome コンポーネントは /welcome エンドポイントでアクセスされます。

対話型サーバー側レンダリング (対話型 SSR) を有効にする

静的サーバー側レンダリング (静的 SSR) の追加」セクションのガイダンスに従います。

アプリの Programファイルで、Razor コンポーネント サービスが AddRazorComponents で追加される位置に AddInteractiveServerComponents の呼び出しを追加します。

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

Razor コンポーネントが MapRazorComponents でマップされている AddInteractiveServerRenderMode への呼び出しを追加してください。

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

対話型サーバー側レンダリング (対話型 SSR) を採用するアプリに次の Counter コンポーネントを追加します。

Components/Pages/Counter.razor:

@page "/counter"
@rendermode InteractiveServer

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

アプリを実行すると、Counter コンポーネントは /counter でアクセスされます。

対話型自動 (Auto) またはクライアント側レンダリング (CSR) を有効にする

静的サーバー側レンダリング (静的 SSR) の追加」セクションのガイダンスに従います。

対話型自動レンダリング モードを使用するコンポーネントは、最初は対話型 SSR を使用します。 .NET ランタイムとアプリ バンドルがバックグラウンドでクライアントにダウンロードされ、キャッシュされるため、以降のアクセスで使用できます。 対話型 WebAssembly レンダリング モードを使用するコンポーネントは、Blazor バンドルがダウンロードされて Blazor ランタイムがアクティブ化された後にのみ、クライアント上で対話形式でレンダリングされます。 対話型自動または対話型 WebAssembly レンダリング モードを使用する場合、クライアントにダウンロードされたコンポーネント コードはプライベート "ではない" ことに留意してください。 詳細については、「ASP.NET Core Blazor レンダリング モード」を参照してください。

採用するレンダリング モードを決定した後の手順:

Microsoft.AspNetCore.Components.WebAssembly.Server NuGet パッケージのパッケージ参照をアプリに追加してください。

Note

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

ドナー Blazor Web アプリを作成して、アプリに資産を提供します。 「ASP.NET Core Blazor 用のツール」の記事のガイダンスに従い、Blazor Web アプリの生成時に次のテンプレート機能のサポートを選択してください。

アプリの名前は、ASP.NET Core アプリと同じ名前を使用してください。これにより、コンポーネント内のアプリ名マークアップが一致し、コード内の名前空間が一致します。 資産をドナー アプリから ASP.NET Core アプリに移動した後に名前空間を調整できるため、同じ名前または名前空間の使用は厳密には必須ではありません。 ただし、最初に名前空間を照合すると時間を節約できます。

Visual Studio:

  • 対話型レンダリング モードでは、[自動] (サーバーと WebAssembly) を選択します。
  • [対話機能の場所][ページ/コンポーネントごと] に設定してください。
  • [サンプル ページを含める] のチェックボックスの選択を解除してください。

.NET CLI:

  • -int Auto オプションを使用します。
  • -ai|--all-interactive オプションは使用 "しないでください"。
  • -e|--empty オプションを渡してください。

ドナー Blazor Web アプリから、.Client プロジェクト全体を ASP.NET Core アプリのソリューション フォルダーにコピーしてください。

重要

ASP.NET Core プロジェクトの .Client フォルダーにフォルダーをコピーしないでください。 .NET ソリューションを整理するための最善の方法は、ソリューションの各プロジェクトを最上位のソリューション フォルダー内の独自のフォルダーに配置することです。 ASP.NET Core プロジェクトのフォルダーの上にソリューション フォルダーが存在しない場合は、作成してください。 次に、.Client プロジェクトのフォルダーを、ドナー Blazor Web アプリからソリューション フォルダーにコピーしてください。 最終的なプロジェクト フォルダー構造は、次のレイアウトになります。

  • BlazorSampleSolution (最上位レベルのソリューション フォルダー)
    • BlazorSample (元の ASP.NET Core プロジェクト)
    • BlazorSample.Client (ドナー Blazor Web アプリからの .Client プロジェクト フォルダー)

ASP.NET Core ソリューション ファイルの場合は、ASP.NET Core プロジェクトのフォルダーに残すことができます。 または、プロジェクトがソリューション フォルダー内の 2 つのプロジェクトのプロジェクト ファイル (.csproj) を正しく参照している限り、ソリューション ファイルを移動したり、最上位のソリューション フォルダーに新しいファイルを作成したりできます。

ASP.NET Core アプリと同じドナー プロジェクトを作成したときに、ドナー Blazor Web アプリに名前を付けた場合、寄付された資産によって使用される名前空間は、ASP.NET Core アプリのそれと一致します。 名前空間を一致させるためのその他の手順は必要ありません。 ドナー Blazor Web App プロジェクトの作成時に別の名前空間を使用した場合は、このガイダンスの残りの部分を記されているとおりに使用する場合、寄付された資産全体の名前空間を調整する必要があります。 名前空間が一致しない場合は、先に進む前に名前空間を調整するか、"または"、このセクションの残りのガイダンスに従って名前空間を調整してください。

ドナー Blazor Web アプリは、このプロセスではこれ以上使用されないため、削除してください。

ソリューションに .Client プロジェクトを追加します。

  • Visual Studio: ソリューション エクスプローラーでソリューションを右クリックし、[追加]>[既存のプロジェクト]の順に選択してください。 .Client フォルダーに移動し、プロジェクト ファイル (.csproj) を選択してください。

  • .NET CLI: dotnet sln add コマンドを使用して、.Client プロジェクトをソリューションに追加してください。

ASP.NET Core プロジェクトからクライアント プロジェクトにプロジェクト参照を追加します。

  • Visual Studio: ASP.NET Core プロジェクトを右クリックし、[追加]>[プロジェクト参照] の順に選択してください。 .Client プロジェクトを選択し、[OK] を選択してください。

  • .NET CLI: ASP.NET Core プロジェクトのフォルダーから、次のコマンドを使用してください。

    dotnet add reference ../BlazorSample.Client/BlazorSample.Client.csproj
    

    上記のコマンドは、次を前提としています。

    • プロジェクト ファイル名は BlazorSample.Client.csproj
    • .Client プロジェクトは、ソリューション フォルダー内の BlazorSample.Client フォルダーにある。 .Client フォルダーは、ASP.NET Core プロジェクトのフォルダーと並んで表示される。

    dotnet add reference コマンドの詳細については、dotnet add reference (.NET のドキュメント) を参照してください。

ASP.NET Core アプリの Program ファイルに次の変更を加えてください。

  • AddInteractiveWebAssemblyComponents で対話型の WebAssembly コンポーネント サービスを追加してください。Razor コンポーネント サービスは AddRazorComponents で追加されます。

    対話型の自動レンダリングの場合:

    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents()
        .AddInteractiveWebAssemblyComponents();
    

    対話型の WebAssembly レンダリングの場合のみ:

    builder.Services.AddRazorComponents()
        .AddInteractiveWebAssemblyComponents();
    
  • 対話型の WebAssembly レンダリング モード (AddInteractiveWebAssemblyRenderMode) と、MapRazorComponents で Razor コンポーネントがマップされる .Client プロジェクトの追加アセンブリを追加してください。

    対話型自動 (Auto) レンダリングの場合:

    app.MapRazorComponents<App>()
        .AddInteractiveServerRenderMode()
        .AddInteractiveWebAssemblyRenderMode()
        .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
    

    対話型の WebAssembly レンダリングの場合のみ:

    app.MapRazorComponents<App>()
        .AddInteractiveWebAssemblyRenderMode()
        .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
    

    前の例では、.Client プロジェクトの名前空間に合わせて BlazorSample.Client 変更してください。

Pages フォルダーを .Client プロジェクトに追加してください。

ASP.NET Core プロジェクトに既存の Counter コンポーネントがある場合:

  • .Client プロジェクトの Pages フォルダーにコンポーネントを移動してください。
  • コンポーネント ファイルの先頭にある @rendermode ディレクティブを削除してください。

ASP.NET Core アプリに Counter コンポーネントがない場合は、次の Counter コンポーネント (Pages/Counter.razor) を .Client プロジェクトに追加してください。

@page "/counter"
@rendermode InteractiveAuto

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

アプリで対話型の WebAssembly レンダリングのみが採用されている場合は、@rendermode ディレクティブと値を削除してください。

- @rendermode InteractiveAuto

"ASP.NET Core アプリ" プロジェクトからソリューションを実行してください。

  • Visual Studio: アプリの実行時にソリューション エクスプローラーで ASP.NET Core プロジェクトが選択されていることを確認してください。

  • .NET CLI: ASP.NET Core プロジェクトのフォルダーからプロジェクトを実行してください。

Counter コンポーネントを読み込むには、/counterに移動してください。

ページまたはビューでルーティングできないコンポーネントを使用する

次のガイダンスを使用して、コンポーネント タグ ヘルパーで既存の Razor Pages または MVC アプリのページとビューに Razor コンポーネントを統合します。

サーバーのプリレンダリングが使用され、ページまたはビューがレンダリングされるときは:

  • ページまたはビューと共にコンポーネントがプリレンダリングされます。
  • プリレンダリングに使用された初期のコンポーネント状態は失われます。
  • SignalR 接続が確立されると、新しいコンポーネント状態が作成されます。

非対話型の静的コンポーネント レンダリングを含むレンダリング モードの詳細については、「ASP.NET Core のコンポーネント タグ ヘルパー」を参照してください。 プリレンダリングされた Razor コンポーネントの状態を保存するには、「ASP.NET Core でのコンポーネントの状態保持タグ ヘルパー」を参照してください。

プロジェクトのルート フォルダーに Components フォルダーを追加します。

次の内容でインポート ファイルを Components フォルダーに追加します。 {APP NAMESPACE} プレースホルダーをプロジェクトの名前空間に変更します。

Components/_Imports.razor:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components

プロジェクトのレイアウト ファイル (Razor Pages アプリの Pages/Shared/_Layout.cshtml、または MVC アプリの Views/Shared/_Layout.cshtml):

  • 次の <base> タグと HeadOutlet コンポーネントのコンポーネント タグ ヘルパーを、<head> マークアップに追加します。

    <base href="~/" />
    <component type="typeof(Microsoft.AspNetCore.Components.Web.HeadOutlet)" 
        render-mode="ServerPrerendered" />
    

    前の例の href 値 (アプリ ベースのパス) は、アプリがルート URL パス (/) に置かれていることを前提としています。 アプリがサブアプリケーションになっている場合は、「ASP.NET Core Blazor のホストと展開」記事の「アプリのベース パス」セクションのガイダンスに従ってください。

    HeadOutlet コンポーネントは、Razor コンポーネントによって設定されたページタイトル (PageTitle コンポーネント) とその他の head 要素 (HeadContent コンポーネント) の head (<head>) コンテンツをレンダリングするために使用されます。 詳しくは、「ASP.NET Core Blazor アプリで コンテンツを制御する」をご覧ください。

  • blazor.web.js スクリプトの <script> タグを、Scripts レンダリング セクション (@await RenderSectionAsync(...)) の直前に追加します。

    <script src="_framework/blazor.web.js"></script>
    

    Blazor フレームワークによって blazor.web.js スクリプトがアプリに追加されるため、アプリに blazor.web.js スクリプトを手動で追加する必要はありません。

Note

通常、レイアウトは _ViewStart.cshtml ファイルを介して読み込まれます。

操作なし (no-op) App コンポーネントをプロジェクトに追加します。

Components/App.razor:

@* No-op App component *@

サービスが登録されるときに、Razor コンポーネントのサービスと対話型サーバー コンポーネントのレンダリングをサポートするサービスを追加します。

Program ファイルの先頭で、プロジェクトのコンポーネント用のファイルの先頭に using ステートメントを追加します。

using {APP NAMESPACE}.Components;

上記の行では、{APP NAMESPACE} プレースホルダーをアプリの名前空間に変更します。 次に例を示します。

using BlazorSample.Components;

Program ファイルのアプリをビルドする行 (builder.Build()) の前で:

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

対話型サーバーおよび WebAssembly コンポーネントのサポートの追加に関する詳細については、「ASP.NET Core Blazor のレンダー モード」を参照してください。

Program ファイルにおいて、Razor Pages アプリで Razor Pages をマップする呼び出し (MapRazorPages)、または MVC アプリで既定のコントローラー ルートをマップする呼び出し (MapControllerRoute) の直後に、MapRazorComponents を呼び出して使用可能なコンポーネントを検出し、アプリのルート コンポーネント (最初に読み込まれるコンポーネント) を指定します。 既定では、アプリのルート コンポーネントは App コンポーネント (App.razor) です。 AddInteractiveInteractiveServerRenderMode の呼び出しをチェーン化して、アプリの対話型サーバー側レンダリング (対話型 SSR) を構成します。

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

Note

アプリが Antiforgery ミドルウェアを含むようにまだ更新されていない場合は、UseAuthorization が呼び出された後に次の行を追加します。

app.UseAntiforgery();

コンポーネントを任意のページまたはビューに統合します。 たとえば、プロジェクトの Components フォルダーに EmbeddedCounter コンポーネントを追加します。

Components/EmbeddedCounter.razor:

<h1>Embedded Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Razor Pages:

Razor Pages アプリのプロジェクトの Index ページで、EmbeddedCounter コンポーネントの名前空間を追加し、そのコンポーネントをページに埋め込みます。 Index ページが読み込まれるとき、EmbeddedCounter コンポーネントはページにプリレンダリングされます。 次の例では、{APP NAMESPACE} プレースホルダーをプロジェクトの名前空間に置き換えます。

Pages/Index.cshtml:

@page
@using {APP NAMESPACE}.Components
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<component type="typeof(EmbeddedCounter)" render-mode="ServerPrerendered" />

MVC:

MVC アプリのプロジェクトの Index ビューで、EmbeddedCounter コンポーネントの名前空間を追加し、そのコンポーネントをビューに埋め込みます。 Index ビューが読み込まれるとき、EmbeddedCounter コンポーネントはページにプリレンダリングされます。 次の例では、{APP NAMESPACE} プレースホルダーをプロジェクトの名前空間に置き換えます。

Views/Home/Index.cshtml:

@using {APP NAMESPACE}.Components
@{
    ViewData["Title"] = "Home Page";
}

<component type="typeof(EmbeddedCounter)" render-mode="ServerPrerendered" />

ルーティング可能なコンポーネントを使用する

次のガイダンスを使用して、既存の Razor Pages または MVC アプリにルーティング可能な Razor コンポーネントを統合します。

このセクションのガイダンスでは、次のことを前提としています。

  • アプリのタイトルは Blazor Sample です。
  • アプリの名前空間は BlazorSample です。

ルーティング可能な Razor コンポーネントをサポートするには:

プロジェクトのルート フォルダーに Components フォルダーを追加します。

次の内容でインポート ファイルを Components フォルダーに追加します。

Components/_Imports.razor:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components

{APP NAMESPACE} プレースホルダーをプロジェクトの名前空間に変更します。 次に例を示します。

@using BlazorSample
@using BlazorSample.Components

Components フォルダーに Layout フォルダーを追加します。

フッター コンポーネントとスタイルシートを Layout フォルダーに追加します。

Components/Layout/Footer.razor:

<footer class="border-top footer text-muted">
    <div class="container">
        &copy; 2023 - {APP TITLE} - <a href="/privacy">Privacy</a>
    </div>
</footer>

前のマークアップで、{APP TITLE} プレースホルダーをアプリのタイトルに設定します。 次に例を示します。

&copy; 2023 - Blazor Sample - <a href="/privacy">Privacy</a>

Components/Layout/Footer.razor.css:

.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

ナビゲーション メニュー コンポーネントを Layout フォルダーに追加します。

Components/Layout/NavMenu.razor:

<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
    <a class="navbar-brand" href="/">{APP TITLE}</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
        <ul class="navbar-nav flex-grow-1">
            <li class="nav-item">
                <a class="nav-link text-dark" href="/">Home</a>
            </li>
            <li class="nav-item">
                <a class="nav-link text-dark" href="/privacy">Privacy</a>
            </li>
            <li class="nav-item">
                <a class="nav-link text-dark" href="/counter">Counter</a>
            </li>
        </ul>
    </div>
</div>
</nav>

前のマークアップで、{APP TITLE} プレースホルダーをアプリのタイトルに設定します。 次に例を示します。

<a class="navbar-brand" href="/">Blazor Sample</a>

Components/Layout/NavMenu.razor.css:

a.navbar-brand {
    white-space: normal;
    text-align: center;
    word-break: break-all;
}

a {
    color: #0077cc;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.border-top {
    border-top: 1px solid #e5e5e5;
}

.border-bottom {
    border-bottom: 1px solid #e5e5e5;
}

.box-shadow {
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}

button.accept-policy {
    font-size: 1rem;
    line-height: inherit;
}

メイン レイアウト コンポーネントとスタイルシートを Layout フォルダーに追加します。

Components/Layout/MainLayout.razor:

@inherits LayoutComponentBase

<header>
    <NavMenu />
</header>

<div class="container">
    <main role="main" class="pb-3">
        @Body
    </main>
</div>

<Footer />

<div id="blazor-error-ui">
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">🗙</a>
</div>

Components/Layout/MainLayout.razor.css:

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

次の内容で Routes コンポーネントを Components フォルダーに追加します。

Components/Routes.razor:

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

次の内容で App コンポーネントを Components フォルダーに追加します。

Components/App.razor:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{APP TITLE}</title>
    <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="/css/site.css" />
    <link rel="stylesheet" href="/{APP NAMESPACE}.styles.css" />
    <HeadOutlet />
</head>
<body>
    <Routes />
    <script src="/lib/jquery/dist/jquery.min.js"></script>
    <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="/js/site.js"></script>
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

上記のコードの、アプリのタイトルとスタイルシートのファイル名を次のように更新します。

  • <title> 要素の {APP TITLE} プレースホルダーには、アプリのタイトルを設定します。 次に例を示します。

    <title>Blazor Sample</title>
    
  • スタイルシートの <link> 要素の {APP NAMESPACE} プレースホルダーには、アプリの名前空間を設定します。 次に例を示します。

    <link rel="stylesheet" href="/BlazorSample.styles.css" />
    

サービスが登録されるときに、Razor コンポーネントのサービスと対話型サーバー コンポーネントのレンダリングをサポートするサービスを追加します。

Program ファイルの先頭で、プロジェクトのコンポーネント用のファイルの先頭に using ステートメントを追加します。

using {APP NAMESPACE}.Components;

上記の行では、{APP NAMESPACE} プレースホルダーをアプリの名前空間に変更します。 次に例を示します。

using BlazorSample.Components;

Program ファイルのアプリをビルドする行 (builder.Build()) の前で:

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

対話型サーバーおよび WebAssembly コンポーネントのサポートの追加に関する詳細については、「ASP.NET Core Blazor のレンダー モード」を参照してください。

Program ファイルで Razor Pages のマッピング (MapRazorPages) を呼び出した後、すぐにMapRazorComponents を呼び出して使用可能なコンポーネントを検出し、アプリのルート コンポーネントを指定してください。 既定では、アプリのルート コンポーネントは App コンポーネント (App.razor) です。 AddInteractiveServerRenderMode の呼び出しをチェーン化して、アプリの対話型サーバー側レンダリング (対話型 SSR) を構成します。

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

Note

アプリが Antiforgery ミドルウェアを含むようにまだ更新されていない場合は、UseAuthorization が呼び出された後に次の行を追加します。

app.UseAntiforgery();

ルーティング可能なコンポーネントの Components フォルダーに Pages フォルダーを作成します。 次の例は、Blazor プロジェクト テンプレート内の Counter コンポーネントに基づく Counter コンポーネントです。

Components/Pages/Counter.razor:

@page "/counter"
@rendermode InteractiveServer

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

プロジェクトを実行し、/counter のルーティング可能な Counter コンポーネントに移動します。

名前空間の詳細については、「コンポーネントの名前空間」セクションを参照してください。

MVC コントローラー アクションから RazorComponentResult を返す

MVC コントローラー アクションは、RazorComponentResult<TComponent> でコンポーネントを返すことができます。

Components/Welcome.razor:

<PageTitle>Welcome!</PageTitle>

<h1>Welcome!</h1>

<p>@Message</p>

@code {
    [Parameter]
    public string? Message { get; set; }
}

コントローラーで:

public IResult GetWelcomeComponent()
{
    return new RazorComponentResult<Welcome>(new { Message = "Hello, world!" });
}

レンダリングされたコンポーネントの HTML マークアップのみが返されます。 レイアウトと HTML ページ マークアップは、コンポーネントと共に自動的にレンダリングされることはありません。 完全な HTML ページを生成するために、<html><head><body> およびその他のタグの HTML マークアップを提供する Blazor レイアウトをアプリで維持できます。 コンポーネントには、コンポーネント定義ファイル (このセクションの例では Welcome.razor) の先頭に @layoutRazor ディレクティブを使用したレイアウトが含まれています。 次の例は、アプリで RazorComponentResultLayout という名前のレイアウトが使われていることを前提としています (Components/Layout/RazorComponentResultLayout.razor):

@using BlazorSample.Components.Layout
@layout RazorComponentResultLayout

Layout フォルダーについての @using ステートメントを個々のコンポーネントに配置することを避けるには、アプリの _Imports.razor ファイルに移動します。

詳しくは、「ASP.NET Core の Blazor レイアウト」を参照してください。

コンポーネントの名前空間

カスタム フォルダーを使用してプロジェクトの Razor コンポーネントを保持する場合は、フォルダーを表す名前空間を、ページまたはビューのいずれかに追加するか、_ViewImports.cshtml ファイルに追加します。 次に例を示します。

  • コンポーネントはプロジェクトの Components フォルダーに格納されます。
  • {APP NAMESPACE} プレースホルダーはロジェクトの名前空間です。 Components はフォルダーの名前を表します。
@using {APP NAMESPACE}.Components

次に例を示します。

@using BlazorSample.Components

_ViewImports.cshtml ファイルは、Razor Pages アプリの Pages フォルダーまたは MVC アプリの Views フォルダーにあります。

詳細については、「ASP.NET Core Razor コンポーネント」を参照してください。

その他のリソース

ASP.NET Core Razor コンポーネントのプリレンダリング