ASP.NET Core Blazor WebAssembly の必要最低限のハロー ワールド

公開:2021/02/15
更新:2021/02/15
4 min読了の目安(約4100字TECH技術記事

ASP.NET Core Blazor WebAssembly を使うと C# + HTML/CSS + JavaScript (必要に応じて使う) で SPA が作れるようになります。WebAssembly 万歳ですね。

LTS になるのは .NET 6 の見込みなので、まだ .NET 6 になったタイミングで色々動きがあるかもしれませんが、今のうちからキャッチアップしておくのには面白い技術の 1 つだと思います。

ということで、何事もハローワールドから。プロジェクトテンプレートで作成するとルーティングとか色々追加されているので (それはそれで有難いのですが) 本当に必要最低限のコードでハローワールドをしてみたいと思います。

Let's "Hello world"

では Visual Studio 2019 (VS Code の場合は dotnet コマンドなどで同等の作業をしてください) で新規プロジェクトから「コンソール アプリ (.NET Core)」を選びます。
プロジェクト名は適当で大丈夫ですが、私は BlazorHelloWorld にしました。

プロジェクトファイルを Blazor WASM 仕様に変更していきます。
元は以下のようになっています。

BlazorHelloWorld.csproj
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

</Project>

これを以下のようにします。ポイントは Project タグの Sdk 属性を Microsoft.NET.Sdk.BlazorWebAssembly にしている点と TargetFrameworknet5.0 にしている点と Blazor WebAssembly に関するパッケージを追加しているところです。

BlazorHelloWorld.csproj
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.3" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.3" PrivateAssets="all" />
  </ItemGroup>

</Project>

この書き換えを行うとプロジェクトの再読み込みを求められるので、再読み込みをします。
次はエントリーポイントの Program.cs を開いて以下のように書き換えます。ここで WebAssemblyHostBuilder を使ってルートのコンポーネントの App を id が app のタグに紐づけています。

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

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
await builder.Build().RunAsync();

// とりあえず App コンポーネントが無いと始まらないのでここに仮で定義
class App : ComponentBase { }

次に、wwwroot フォルダーをプロジェクトに作成して index.html を作成します。このファイルがブラウザーで開かれます。

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Hello world</title>
</head>
<body>
    <div id="app">Loading...</div>
    <script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

この時点でプロジェクトを実行できるようになっています。実行してみましょう。
一瞬 Loading... と表示された後に以下のように真っ白な画面になると思います。

この時起きていることは index.html に記述されている <div id="app">Loading...</div> が最初に表示されて、そこに Blazor WASM が App コンポーネントをレンダリングされているために起きています。現状 App コンポーネントは空なので真っ白な画面になっています。

では、仕上げです。Hello world を印字しましょう。
2 通りの方法でやろうと思います。razor ファイルを作ラナイ方法と razor ファイルを作る方法です。まずは作らない方でやってみます。

Blazor のコンポーネントは BuildRenderTree メソッドで出力する内容をコードで組み立てることが出来ます。タグを出力したりコンテンツを出力したり属性を出力したりなど色々なことが出来ます。まぁ、これは低レベルな API なので、普通は使いませんがパフォーマンス命みたいなコンポーネントを作るときは使うことがある感じです。

まぁ今回は単純に Hello world を出すだけなのでそんなに難しくありません。App コンポーネントに BuildRenderTree メソッドを追加して以下のように h3 タグで括って Hello world を出力するコードを書きます。

class App : ComponentBase 
{
    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.OpenElement(0, "h3");
        builder.AddContent(1, "Hello world");
        builder.CloseElement();
    }
}

実行すると、さっきまで真っ白だった画面に Hello world が表示されます。やったね!

次は Program.cs から App クラスの定義を削除して App.razor という名前で「Razor コンポーネント」を追加します。因みに App.razor という名前であればテキストファイルをプロジェクトの下に置くだけでも大丈夫です。

そして、App.razor の中を以下のように変更します。

App.razor
<h3>Hello world</h3>

この変更を行うと Program.cs でコンパイルエラーが起きると思います。これは単純に .razor 形式のファイルから生成されたクラスがプロジェクトのデフォルトの名前空間の中に作られるからです。using を追加してあげましょう。Program.cs は以下のようになります。

Pogram.cs
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using BlazorHelloWorld; // 追加!

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
await builder.Build().RunAsync();

この状態で実行すると、画面に Hello world が表示されます。実行結果は先ほどと同じなので画像は省略します。

まとめ

ということで、Blazor WebAssembly の必要最低限のハローワールドを作ってみました。
土台部分を押さえることで、残りの部分は何らかの機能を実現するための追加部分だということがわかるので、そういったものを把握するうえでも自分は、何かやるときにはこういった必要最低限のハローワールドを作るのが好きです。

ということで、良い Blazor 生活を。