deezus blog

.Net Core、Typescriptを中心に技術的ノウハウを公開しています

C#でWebAssemblyが開発できるBlazorを試してみる

はじめに

現時点(2018/10/21)ではプレビュー段階ですがC#でWebAssemblyを開発することができるBlazorというものがあります
https://blazor.net/
これを使うことでWebシステムにおいてサーバサイドとクライアントサイドの両方をC#で開発することができます
現在クライアントサイドはAngularを使用することが多いのですが、Blazorが良さそうなら将来的に乗り換えようと思い調査しました

準備

公式サイトを参考に.NetCoreなどをインストールします
VisualStudioを使わない場合は.NetCoreSDKインストール後に下記コマンドでプロジェクトテンプレートをインストールするだけでOKです

dotnet new -i Microsoft.AspNetCore.Blazor.Templates

サンプルではプロジェクト作成時に

dotnet new blazor -o BlazorApp1

としていますが、サーバサイドも作成する場合は以下のようにします

dotnet new blazorserverside -o BlazorApp1

すると以下のようにプロジェクトが3つ作成されます(***はプロジェクト名)

***.Clientクライアントサイド
***.Serverサーバサイド
***.Shareクライアント、サーバで共通で使用するクラスなど
例えばAjaxでやりとりするクラスなど

クライアントサイドにTypescriptを使用する場合、AjaxでサーバサイドとやりとりをするためのクラスをTypescriptで定義し、ほぼ同じクラスをサーバサイドのC#でも定義する必要があります
Blazorを使用すればAjaxで使用するクラスを.Shareに定義し、クライアントサイドとサーバサイドで共通で使えるので、Typescriptの場合のように2重に定義する必要がなくなります

Clientの解説

コンポーネント

AngularやReactなどと同様にコンポーネント指向です
コンポーネントを作るにはClienプロジェクト内の任意のディレクトリに***.cshtmlとファイルを作成すればOKです
例えば現在時刻を表示するTimeコンポーネントを作成する場合、以下のようになります
Time.cshtml

<p>@_now.ToString("yyyy/MM/dd HH:mm:ss")</p>
@functions
{
    DateTime _now;
    protected override void OnInit()
    {
        _now = DateTime.Now;
    }   
}

@functionaブロックに処理を記載します
OnInitはコンポーネントが読み込まれる時に呼び出されます
AngularのngOnInitのようなものです

使用するときはファイル名がそのままタグになります

<Time />

ルーティング

URLと紐づける場合はcshtmlに紐づけたいURLを以下のように記載します

@page "/"

パラメータを受け取りたい場合はASP.NET Core MVCと同様に{}で指定します
@functionsブロックに[Parameter]をつけた同名のプロパティを定義すればパラメータを受け取れます

@page "/item/{id}"

<p>@Id</p>
@functions
{
    [Parameter]
    string Id { get; set; }
}

プロパティの型を指定することができます

@page "/item/{id:int}"

<p>@Id</p>
@functions
{
    [Parameter]
    int Id { get; set; }
}

イベント

onClickなどは@+メソッド名で指定できます

<button onclick="@Click">click</button>
@functions
{
    void Click(){
    }
}

onsubmitの場合

<form onsubmit="@Submit">
    <input type="text" />
    <button>送信</button>
</form>
@functions
{
    void Submit(){
    }
}

Ajax

Ajaxを使用するにはcshtmlにHttpClientをDIします

@inject HttpClient Http

使い方は以下の通りです

<button onclick="@click">Click</button>
@functions{
    async Task Submit()
    {
        var data = await Http.GetJsonAsync(URL);
    }
}

おわりに

現状プレビュー版ということで今後どうなるか楽しみです
個人的には、クライアント側を変更した場合も再度ビルドしないと画面に反映されないのでホットリロードのようなものが欲しいと思います

サーバサイドも含めてサンプルとして簡単な掲示板を作成しました
https://github.com/deezus-net/blazor-bbs