Visual Studio をダウンロードしたら、まず Blazor ソリューションを作成し、その中に Blazor Server プロジェクトを作成します。ソリューションの場所は自由に選んで構いません(注:新しいバージョンの Visual Studio では、Blazor Server と Blazor WebAssembly の新規プロジェクトテンプレートが分割されており、よりわかりやすくなっています)。まずはプログラムの中身は気にせず、F5 キーを押して実行し、Web ページ上で F12 キーまたは Ctrl+Shift+I キーを押して開発者ツール(Dev tool)を開き、Network タブに切り替えてから Web ページを再読み込みします。いくつかのファイルが表示されますが、そのうちの blazor.server.js は、サーバーとブラウザ間で SignalR を介して WebSocket チャネルを確立するためのファイルです。









次に、ブラウザにダウンロードされたファイルをすべてクリアし、Counter と Fetch data のページをクリックします。以前の Web サイトでは、これはページの更新操作であり、そのページに必要なファイルが再ダウンロードされていました。しかし、これらの2つのページでは何もダウンロードされていないことがわかります(favicon.ico はダウンロードされますが、賢明な読者であればその理由がおわかりでしょう)。なぜなら、最初の接続が確立された後は、以降のファイル転送はすべて SignalR を介して行われるからです。


続いて、同じソリューション内に Blazor WebAssembly プロジェクトを作成します。ここには「プログレッシブ Web アプリケーション」オプションがあり、これを選択すると、この Web サイトをコンピューターにダウンロードできるようになります。



プロジェクトの作成後、直接プロジェクトを起動できますが、Blazor Server と Blazor WebAssembly の両方を同時に起動したい場合はどうすればよいでしょうか。両方のプロジェクトをスタートアッププロジェクトとして設定し、F5 キーを押してプロジェクトを起動します。




筆者が数か月前に開発していたときは、ダウンロードされた多くの DLL ファイルが表示されていましたが、現在の Blazor WebAssembly がブラウザに送信するファイルは Blazor Server と大差ありません。これは、マイクロソフトが Blazor WebAssembly の DLL ダウンロードルールを変更し、コンポーネントがリクエストを送信したときだけブラウザにダウンロードされるようにしたためであり、ブラウザの負荷が大幅に軽減されています。

次にプロジェクト構造を見ていきます。便宜上、両者で対応するファイルを同じ色で囲み、番号を付けています。まず5番を見てください。Blazor Server と Blazor WebAssembly の両方に Program.cs があり、両者のプログラムのエントリポイントは Program.cs です。

Blazor Server の Program.cs ファイル:

Blazor Wasm の Program.cs ファイル:

どちらのプロジェクトも、builder.Services を介してサービスを注入しています。.NET 6 プレビュー版またはそれ以前のバージョンでは、Startup.cs ファイルが追加されており、ConfigureServices メソッドで「サービスの構成」(関連するサービスを使用する必要がある場合は、ここで依存性注入(Dependency Injection: DI)を使用する必要があります。依存性注入の利点については後述します)を行っていました。両者の役割は同じであり、.NET 6 はすっきりしていて見やすくなったのではないでしょうか。
var app = builder.Build(); で取得した app インスタンスは、以前の Startup.cs の Configure メソッドと同様の役割を果たします。これは、リクエストの処理やミドルウェアの登録を行う場所です。たとえば、他人が作成した認証パッケージを使用したい場合は、ここで登録する必要があります。ルーティングの定義もここで行います。MapBlazorHub() は、サーバーとブラウザ間の SignalR 接続を確立するメソッドです。MapFallbackToPage("/_Host") は、Web ページのエントリポイントが _Host であることを意味し、Controller や razor page 以外のリクエスト(つまり、最初の接続時や接続エラー時)はここから入ります。その後、コンポーネントのトリガーは、6番の枠で示した App.razor の変更を通じて行われます。


次に2番の枠を見てください。Blazor Server には _Host.cshtml、_Layout.cshtml、Error.cshtml が追加されています。_Host.cshtml については前述しました。_Layout.cshtml(Blazor Server の場合)と index.html(Blazor Wasm の場合)は類似しており、Web サイトのメインページです。Error.cshtml は接続エラー時に導かれるページです。その他の .razor 拡張子のファイルは、1つ1つのコンポーネントです。
3番の枠は両方のプロジェクトで共通です。MainLayout.razor、NavMenu.razor はそれぞれ Web ページのレイアウトとメニューです。Web サイトのすべてのページで同じサイドバーやメニューを使用し、更新(会社のロゴの変更、連絡先の追加など)のたびにすべてのページを処理するのは非効率的です。そこで Blazor ではこれらのページを抽出し、1か所を変更するだけで全ページに適用できるようにしています。SurveyPrompt.razor は Blazor が提供する簡単なサンプルです。_Imports.razor は、@using System; などの使用する名前空間をここに配置します。これにより、各 razor ページで個別に名前空間を参照する必要がなくなります。異なるコンポーネントの名前空間を区別したい場合は、異なるフォルダーに独立した _Imports.razor ファイルを作成することもできます。異なるフォルダーの _Imports.razor は、そのフォルダー内のコンポーネントにのみ作用します。
最後に、1番の枠の wwwroot フォルダーです。Blazor WebAssembly には sample-data ディレクトリ、icon-192.png、index.html が追加されています。sample-data ディレクトリはブラウザにダウンロードされる天気データ、icon-192.png はどこで使用されているかは不明です。index.html は Blazor Server の _Host.cshtml に相当するファイルです(前の段落で言及しました)。
一方、Blazor Server にはまだ説明していない Data フォルダーがありますが、その中身は何でしょうか。実は、サーバーからブラウザに送信される天気データであり、WeatherForecastService はこの名前を覚えておいてください。後の依存性注入で使用します。

最後に、Blazor Server の appsettings.json です。これは JSON 形式のファイルで、頻繁に変更する必要があるデータ(データベース接続に使用する接続文字列など)をここに配置できます。プログラム内に記述すると、変更のたびにプログラムを再コンパイルする必要がありますが、appsettings.json に配置することで柔軟性が高まります。
注:この記事のコードは .NET 6 + Visual Studio 2022 でリファクタリングされています。原文のリンクをクリックしてリファクタリング後のコードと比較しながら学習してください。ご一読いただきありがとうございます。原作者をサポートします。