Blazor プロジェクトの構成を、Blazor WebAssembly と Blazor Server を比較しながら確認する

本記事ではこれから ASP.NET Core Blazor (以下 Blazor) を使った開発を始めようとしている方を対象に、Blazor プロジェクトの構成について、ひとつずつ確認していこうと思います。

また、Blazor には <a href="https://docs.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-5.0" target="_blank">2つのホスティングモデル</a> (Blazor WebAssembly と Blazor Server) が存在しますので、それぞれのホスティングモデルで作成したプロジェクト構成の違いについても見ていきます。

今回、Blazor WebAssembly と Blazor Server それぞれのホスティングモデルで新規作成したプロジェクトを持つソリューションを用意しました。それぞれ、含まれるファイルおよびフォルダ構成は以下のようになります。

[![Image from Gyazo](https://i.gyazo.com/ca73683d9d784b592b4ebed90883f688.png)](https://gyazo.com/ca73683d9d784b592b4ebed90883f688)

また、インストールおよびプロジェクトの開始方法について <a href="https://blogs.jp.infragistics.com/entry/2020/10/22/161605" target="_blank">こちらの記事</a> で説明していますのでご参照ください。

### Program.cs

[![Image from Gyazo](https://i.gyazo.com/28ed6d9fe6a69e7d6d488aa339b9ded6.png)](https://gyazo.com/28ed6d9fe6a69e7d6d488aa339b9ded6)

エントリーポイントの Main メソッドが含まれるファイルです。

Blazor server では CreateHostBuilder メソッドで <a href="https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-5.0#set-up-a-host" target="_blank">.NET 汎用ホストの設定</a> が行われていることが分かります。

Blazor WebAssembly では Main メソッドの中で、大元のコンポーネントであるルートコンポーネントに App コンポーネント (`App.razor`) を指定しています。コンポーネントは、Blazor アプリケーションを構成する要素です。 <a href="https://docs.microsoft.com/ja-jp/aspnet/core/blazor/components/?view=aspnetcore-5.0" target="_blank">Blazor のコンポーネント</a> は、正式には Razor コンポーネントと呼ばれ、Razor コンポーネントファイル (`.razor`) で実装します。

<!--
    .Net Core の Generic Host とは何か
    https://qiita.com/kitauji/items/a7c6a7d33c9f67c79336
-->
<!--
    コンポーネントは、C# と HTML マークアップの組み合わせを使用して、Razor コンポーネント ファイル (.razor) で実装します。 Blazor のコンポーネントは、正式には Razor コンポーネント と呼ばれます。
    https://docs.microsoft.com/ja-jp/aspnet/core/blazor/components/?view=aspnetcore-5.0
-->

### App.razor

[![Image from Gyazo](https://i.gyazo.com/5f3383f054847cf5cfb5ef0c46543bb2.png)](https://gyazo.com/5f3383f054847cf5cfb5ef0c46543bb2)

Blazor WebAssembly と Blazor Server で同じ記述であることが分かります。このコンポーネントは <a href="https://docs.microsoft.com/ja-jp/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-5.0" target="_blank">ルーティング</a> の役割を持ち、ブラウザのナビゲーションで要求されたアドレスに一致するコンポーネントをレンダリングします。一致するものが見つからない場合は、NotFound プロパティを使用して Page Not Found のようなメッセージを表示しています。また、RouteView コンポーネントに DefaultLayout で MainLayout.razor コンポーネントを指定しています。特に指定がない場合にコンポーネントはこの MainLayout.razor をレイアウトとして使用します。

### wwwroot フォルダ

画像や CSS などの静的なファイルを置くフォルダです。<br>
また、Blazor WebAssembly ではページを表示する際の基本となる `index.html` が配置されています。ブラウザからリクエストが行われると、まずこの `index.html` が返され、読み込まれた WebAssembly JavaScript ファイル(`_framework/blazor.webassembly.js`) によって .NET ランタイム、アプリ、およびアプリの依存関係のダウンロードと、アプリを実行するランタイムの初期化が行われます。また、ルートコンポーネントである App コンポーネントは `<app>` 内にレンダリングされます。

### Pages フォルダ

ルーティングの設定が記載されたいくつかの Razor コンポーネントファイルが格納されています。<br>
Blazor server ではホストページである `_Host.cshtml` ファイルが存在しますが、その中で以下のようにルートコンポーネントとして App コンポーネントを指定していることが分かります。Blazor WebAssembly と同じく、App コンポーネントは `<app>` 内にレンダリングされます。

```
<app>
    <component type="typeof(App)" render-mode="ServerPrerendered" />
</app>
```

<!--
    _Host.cshtml ファイル でルートコンポーネントを指定していることの説明
    https://docs.microsoft.com/ja-jp/aspnet/core/blazor/components/prerendering-and-integration?view=aspnetcore-5.0&pivots=webassembly
-->

### Shared フォルダ

共通で利用するコンポーネントを置くフォルダです。デフォルトのレイアウトを定義した `MainLayout.razor` ファイルと、トップページ (`index.razor`) で読み込んでいるアンケート用のメッセージコンポーネント (`SurveyPrompt.razor`) 、ナビゲーションメニューを定義した `NavMenu.razor` ファイルがあります。 `NavMenu.razor` コンポーネントに含まれている <a href="https://docs.microsoft.com/ja-jp/aspnet/core/blazor/fundamentals/routing?view=aspnetcore-5.0#navlink-component" target="_blank">NavLink コンポーネント</a>は、HTML の `<a>` タグのようにナビゲーションリンクを作成する際に利用できますが、href の値が現在の URL と一致している場合に自動的に active クラスを付与するという点でより優れています。

### _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 Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorApp_WebAssembly
@using BlazorApp_WebAssembly.Shared
```

共通の名前空間に関して、このコンポーネントで定義することで、このプロジェクトで定義されるすべての Razor コンポーネントにおいて、@using ディレクティブの指定が不要になります。

### Startup.cs

Blazor Server の場合にのみ存在し、アプリの起動ロジックを担当します。依存関係の注入（DI）サービスを構成する ConfigureServices メソッドと、HTTP リクエストのパイプラインを構成する Configure メソッドが含まれています。Blazor Server ではサンプルアプリケーション用のデータサービスを ConfigureServices メソッドで追加していることが分かります。

```
public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
}
```

<!--
    Blazor プロジェクトの構造
    https://docs.microsoft.com/ja-jp/aspnet/core/blazor/templates?view=aspnetcore-5.0

    Owaspでは、 HTTP Strict Transport Security (hsts)は、応答ヘッダーを使用して web アプリによって指定されるオプトインセキュリティ拡張機能です。
    https://docs.microsoft.com/ja-jp/aspnet/core/security/enforcing-ssl?view=aspnetcore-2.1&tabs=visual-studio#http-strict-transport-security-protocol-hsts
-->

### Properties フォルダ

開発環境の設定ファイルである `launchSettings.json` が置かれています。
launchSettings.json に関しては <a href="https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/environments?view=aspnetcore-5.0#development-and-launchsettingsjson" target="_blank">こちらのページ</a> をご参照ください。

### Data フォルダ

Blazor Server 用のサンプルデータを提供する `WeatherForecast` クラスと` WeatherForecastService` の実装が含まれています。

## まとめ

2つのホスティングモデルを比較した時に、コンポーネントレベルでは違いを意識する必要がほとんどないという点が素晴らしいと思いました。
実際にサンプルページのコンポーネントを比較しても、データをサーバから取得する場合と、HttpClient で JSON ファイルから取得する場合で方法が異なる `FetchData` コンポーネント以外はほとんど同じ記述です。<br>
ですので、とりあえず Blazor に触れてみようという理由でプロジェクトを作成される場合には、どちらのホスティングモデルを選んでいただいても問題ないと思います。

２つのホスティングモデルそれぞれの利点、欠点に関しては以下の記事もぜひご覧ください。
<a href="https://blogs.jp.infragistics.com/entry/2020/10/30/152834" target="_blank">ASP.NET Core Blazor - Blazor WebAssembly と Blazor Server の違いは？ ５つのポイント</a>

#### Ignite UI for Blazor トライアル版を利用するには

インフラジスティックスでは充実した UI コンポーネントライブラリーを収録し、データリッチでレスポンシブなWebアプリケーションをより迅速に構築することを可能にする <a href="https://jp.infragistics.com/products/ignite-ui" target="_blank">Ignite UI</a> を開発しており、Blazor 対応の <a href="https://jp.infragistics.com/products/ignite-ui-blazor" target="_blank">Ignite UI for Blazor</a> もリリースしています。
Ignite UI for Blazor はトライアル版での試用が可能です。
トライアル版を利用するためには以下のページよりアカウントの作成を行ってください。登録より30日間、弊社のテクニカルサポートをご利用いただくことが出来ますのでお気軽にお問い合わせください。
https://iam.infragistics.com/Account/Register

また、製品をご購入をご検討のお客様は以下のページよりお気軽にお問い合わせください。
https://jp.infragistics.com/about-us/contact-us