Chapter 04

Hello world

Kazuki Ota
Kazuki Ota
2022.06.26に更新

はじめに

ここでは、ASP.NET Core Blazor WebAssembly の必要最低限のハローワールドを作成します。それを通じて ASP.NET Core Blazor WebAssembly が動作するために必要な構成要素を理解します。

プロジェクトの新規作成とセットアップ

では、プロジェクトの新規作成を行います。ASP.NET Core Blazor WebAssembly のプロジェクトではなくコンソール アプリケーションのプロジェクトを新規作成します。

コンソール アプリケーションのプロジェクト テンプレートは .NET Framework のものと .NET 用の 2 種類のものがあります。ここでは .NET 用のプロジェクト テンプレートで新規作成を行います。プロジェクト名に「HelloBlazorApp」と入力して作成を行います。

ソリューション エクスプローラーでプロジェクト ファイルをダブルクリックして開きます。そうすると以下のような XML 形式のファイルが表示されます。

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

これは、.NET 向けのコンソール アプリケーションのプロジェクトファイルになっているので、以下のように書き換えて Blazor WebAssembly 用にします。

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

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

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

</Project>

Project タグの SDK 属性で BlazorWebAssebmly のプロジェクトであるということを明示して、TargetFramework タグで .NET 6 のプロジェクトであることを設定しています。そして、PackageReference で ASP.NET Core Blazor WebAssembly 関連のパッケージを追加しています。

プロジェクト ファイルを書き換えると Visual Studio でプロジェクトの再読み込みを求められるので再読み込みを行います。

Blazor WebAssembly の適用

次にプロジェクトが実行されたときに表示される index.html を作成します。プロジェクト直下に wwwroot フォルダーを作成して、その中に以下の内容で index.html を作成します。

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

この状態でデバッグ実行を行うと Web ブラウザーが起動して index.html ファイルが表示されます。まだ何も書いていないので真っ白な画面になりますが、Program.cs の内容は実行されています。確認してみましょう。デバッグ実行して表示されたブラウザーで F12 キーを押して開発者ツールを表示させます。そしてコンソールタブを表示すると Hello world と表示されているのが確認できます。

これで、WebAssembly 上で Program.cs の内容が呼ばれるところまで設定できました。ここに Blazor WebAssembly の機能を使って画面を表示していきます。

Program.cs を開いて Main メソッドを変更していきます。

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 { }

Blazor WebAssembly の各種設定を行うための WebAssemblyHostBuilder をデフォルト設定で作成して、Blazor WebAssembly のトップ レベルのコンポーネントと HTML のタグの対応付けを builder.RootComponents.Add<App>("#app"); の行で行っています。ここでは App という名前のコンポーネントと HTML の中で app という id を持ったタグを紐づけしています。

そして、await builder.Build().RunAsync(); で起動しています。最後の行でトップ レベルのコンポーネントとして使用する App を定義しています。

HTML 側に、まだ app という id を持ったタグを定義していないので index.html に以下のように div タグを 1 つ追加して id に app を指定します。

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

これで、デバッグ実行を行うと最初に以下のように「読み込み中…」と表示された後に真っ白な画面になります。

これは、最初に index.html の中身がそのまま表示されるため「読み込み中…」と表示されます。その後 WebAssembly が読み込まれて Program.cs が実行され id が app となっているタグに App コンポーネントを割り当てる処理が走るため表示が更新されます。App コンポーネントには、まだ UI を何も設定していないので真っ白な画面になります。

ハローワールド化

では、App コンポーネントに UI を定義してハローワールドにします。Blazor WebAssembly のコンポーネントでは後程紹介する C# と HTML が混ざったような razor 形式のファイルで UI とそれに伴う処理を書いていくのが一般的ですが、ここではもっとプリミティブな C# で出力するタグを定義する方法で書いていきます。

App クラスで BuildRenderTree メソッドをオーバーライドしてタグを組み立てる処理を追加しています。

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

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

class App : ComponentBase
{
    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        // UI の組み立て(h3 タグを追加してハローワールドを中身に設定)
        builder.OpenElement(0, "h3");
        builder.AddContent(1, "ハローワールド");
        builder.CloseElement();
    }
}

この状態で実行すると以下のようにハローワールドが表示されます。

App コンポーネントを razor ファイルに変更

次に、App コンポーネントの定義を通常使用する razor 形式のファイルに変更します。Program.cs から以下のように App コンポーネントの定義を削除します。

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

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

そして、プロジェクト直下に App.razor という名前のファイルを作成します。Visual Studio 2022 で作成する場合は以下の Razor コンポーネントのアイテムテンプレートを使用して作成してください。

作成された App.razor の中身を以下のように変更します。

App.razor
<h3>こんにちは世界</h3>

ちゃんと App.razor の中身に置き換えられたか確認しやすくするため C# で定義した文字列とは少し変えています。

この状態で実行すると、以下のように表示されます。App.razor で定義した内容が表示されています。

イベント対応

最後に、ハロー ワールドにボタン クリックのイベントを追加します。Blazor WebAssembly では、ボタンのクリックなどのイベントの処理を C# で書くことが出来ます。詳細については後程解説しますが、ここでは必要最低限だけ処理を追加してみましょう。

まず button タグなどの基本的な HTML タグのイベントに対応するイベント ハンドラを定義するためには Microsoft.AspNetCore.Components.Web 名前空間の using が必要になります。

そして、クリック時のイベントのイベントハンドラを追加するには button タグに @click="呼び出されるメソッド名" のように指定します。呼び出されるメソッドの定義は razor ファイルに @code { ... } で囲まれたブロック内で定義します。

@code { ... } で囲まれた部分にはメソッドの他にプロパティやフィールドなどが定義できます。そして @code { ... } 内で定義されたプロパティやメソッドなどは @プロパティ名 などのようにして HTML を記載している部分で参照が可能です。

では、App.razor を以下のように書き換えてみましょう。

App.razor
@using Microsoft.AspNetCore.Components.Web
<h3>@Message</h3>

<button @onclick="ToJapanese">To Japanese</button>

@code {
    private string Message { get; set; } = "Hello world";
    private void ToJapanese() => Message = "こんにちは世界";
}

デバッグ実行を行うと以下のようにボタンがある画面が表示されます。

ボタンを押すと ToJapanese メソッドが呼び出されて Message プロパティの値が更新されて画面もそれにあわせて更新されて以下のようになります。

以上で、ハローワールドの作成は完了です。

まとめ

ここでは、必要最低限の Blazor WebAssembly のプロジェクトの作成を行いました。Blazor WebAssembly のプロジェクトは以下のような流れで起動していることが確認できたと思います。

  1. index.html が読み込まれる
  2. _framework/blazor.webassembly.js が読み込まれる
  3. Program.cs が呼ばれる
  4. Program.cs 内でルート コンポーネントと HTML タグの対応付けが行われる
  5. HTML 内にルート コンポーネントがレンダリングされる

また、App クラスを razor 形式のファイルを使って定義しました。詳しい文法などは解説していませんが以下のような感覚は掴んで頂けたと思います。

  • C# と HTML が混ざったような文法
  • @code { ... } で括られた部分にメソッドやプロパティなどを定義する
  • HTML の部分で @プロパティ名 のような形で参照できる

この先の章では Blazor WebAssembly の個々の機能について、より詳細に解説していきます。