はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

「クライアントサイドBlazor」改め「Blazor WebAssembly」を試してみる

以前は「Client-Side Blazor」と呼ばれていた技術が「Blazor WebAssembly」と呼び方が変わっていました。
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-6.0#blazor-webassembly

Blazor WebAssemblyを使えば、WebサーバーなしでWebブラウザ上でBlazorアプリを動作することができます。
f:id:hatsune_a:20220316134740p:plain
そしてなんといっても「C#」で作成できる点です。

Blazorとは

ここで「Blazor」という言葉を初めて聞いた人向けに、ちょっとだけBlazorとはなに?というお話をしたいと思います。
Blazorは、.NET環境で使用することができるWebブラウザ上で実行可能なアプリを開発するためのフレームワークです。
Blazorで利用する主な言語は「C#」となります。
Blazor Server(ASP.NET Core Blazor)を採用すれば、サーバーサイドも(従来はJavaScriptで記述していたような)クライアントサイドもC#で記述することができます。

2つのBlazor WebAssembly

Blazor WebAssemblyには、次の2つの種類があります。

  1. 単体で動作する「Standalone Blazor WebAssembly」
  2. バックエンドのASP.NET Coreと協調して動作する「Hosted Blazor WebAssembly」

Hosted Blazor WebAssemblyの方がBlazor Serverで動作しているBlazorアプリと同じことができるフル機能を有しています。

フル機能なので想像はしやすいと思いますが、どうせだったらバックエンドとかを用意しなくてもいい完全スタンドアロンなStandalone Blazor WebAssemblyについて、もう少し見ていきたいと思います。
なぜ、こっちを中心にかといえば、最終的な目的は、Blazor WebAssemblyでChrome拡張を作ってみたいというゴールがあるからです。そのときに、ASP.NET Coreなどのクラウド環境を別途用意しなくても動作する形にしてみたいからですね。

Visual Studioで新規プロジェクトを作成する

Visual Studio 2022を起動して[新しいプロジェクトの作成]画面で「Blazor WebAssemblyアプリ」のテンプレートを選択します。
f:id:hatsune_a:20220316140827p:plain
なお、このテンプレートは、Visual Studioのインストール時に「ASP.NETとWeb開発」のワークロードのインストールを行っていないと表示されません。
クライアントアプリしか作らないわーと(比較的大きい)「ASP.NETとWeb開発」のワークロードを行っていなかったときは、良い機会なのでサクッといれてしまいましょう。
f:id:hatsune_a:20220316141126p:plain

プロジェクト名を指定する

f:id:hatsune_a:20220316141308p:plain

追加情報を指定する

追加情報では次のように指定しました。
f:id:hatsune_a:20220316141519p:plain
[ASP.NET Coreでホストされた]チェックボックスにチェックすると「Hosted Blazor WebAssembly」になるので、今回のStandaloneではかならずチェックを外したままにしておきます。

新規プロジェクトの初期状態を確認する

初期状態では次のようなソリューション構成になっています。
f:id:hatsune_a:20220316141900p:plain

初期状態でデバッグ実行してみる

まずはこのままF5でデバッグ実行してみましょう。

証明書を信頼する/しない

するとhttpsを使うとしてプロジェクトをつくったので証明書を信頼するかのダイアログが表示されます。
f:id:hatsune_a:20220316142113p:plain
「はい」でも「いいえ」でもどちらでもよいのでクリックして先に進みます。今回は「いいえ」で進んでみましょう。

初期表示を確認する

Visual Studioの良いところは、テンプレートから作成した新規プロジェクトをそのまま起動しても、ある程度形になったアプリとして動いてくれるところですね。1行も書いてなくても下記のようなStandalone Blazor WebAssemblyアプリが動きます。
f:id:hatsune_a:20220316142805p:plain

テンプレートから作成したアプリの構成を確認する

Blazor WebAssemblyアプリの画面は、プロジェクトの中のPagesフォルダに入っています。
テンプレートから作成した場合は「index.razor」「Counter.razor」「FetchData.razor」の3つの画面が作成されます。

この他に画面共通部品としてSharedフォルダに「MainLayout.razor」「NavMenu.razor」「SurveyPrompt.razor」があります。

index.razor

ホーム画面であるindex.razorの内容は非常にシンプルです。
f:id:hatsune_a:20220316145808p:plain

この定義にSharedフォルダの共通部品を組み合わせると下記のような表示になります。
f:id:hatsune_a:20220316142805p:plain

Counter.razor

画面上のボタンをクリックすると数値がカウントアップしていく画面です。
f:id:hatsune_a:20220316151946p:plain

こちらも定義はシンプルです。
f:id:hatsune_a:20220316151417p:plain
ここで注目してほしいのは、@codeで囲まれた部分(画面ハードコピーでは判定している部分)です。
すごくC#っぽいコードですねというか、いわゆるcsファイルに書くようなC#のコードそのものです。
その直前の@onclickでC#のIncrementCountを呼び出しているのがUI部分からのイベント呼び出し部分ですね。

この表示にhtmlはどうなっているかといえば、これまたシンプル
f:id:hatsune_a:20220316160123p:plain
ロジックコードなどはhtmlなどからは隠ぺいされていて、ブラウザでコードが見られるし書き換えられて実行されるというような心配もありません。
これこそがBlazorですね!

FetchData.razor

3つめの画面は他の2つに比べるとちょっと複雑です。まずは実行結果を見てみましょう。
f:id:hatsune_a:20220316155355p:plain
このように一覧表が表示されますが、表の中の値は直接FetchData.razorには書かれていません。
f:id:hatsune_a:20220316154320p:plain

OnInitializedAsncメソッドは自動的に呼び出されてforecasts変数に表示データを格納しています。

html部分では、forecasts変数がnull以外になったら、else節にあるテーブル表示に移行します。
forecasts変数の状態をポーリングするとかも書かなくていいのがすごいですね。
そして、tbodyのところではC#なforeach構文を使ってデータを1行づつ表示しています。

まとめ

  1. Blazor WebAssemblyはC#でクライアントサイドが書ける優れもの
  2. WebAPIの呼び出しなどもできそう
  3. 画面定義はRazor構文でわかりやすい

.NET 6からWindows Runtime APIを呼ぶのが劇的に楽な件

## .NET 6以前
Windows 10の固有APIにアクセスする方法としては、Windows Runtime API (WinRT API) があります。
Windows Runtime APIはUWPアプリからはすごく使いやすかったのですが、.NET Frameworkから使おうとすると参照設定をしたり、デスクトップブリッジを使ったりと、ひと手間といわず数手間かかるような感じした。

## .NET 6以降
正確には、.NET 5でも同様のようですが、.NET 6では、Windows Runtime APIを使うための準備をほぼ意識しないレベルになっています。

### 準備
f:id:hatsune_a:20220125165818p:plain
Visual Studioでプロジェクトのプロパティで「ターゲットOS」を指定するところでWindows 10のバージョンを指定します。この指定によってcsprojファイルには次のようにWindows 10のランタイムバージョンが指定されます。
f:id:hatsune_a:20220125170057p:plain

### 使い方(コード編)
f:id:hatsune_a:20220125190835p:plain
普通に「Windows.」で始まる名前空間Windows Runtime APIのクラスが使えますね。

### 使い方(xaml編)
f:id:hatsune_a:20220125191342p:plain
Windows.UI.Xaml名前空間がないようです。
これは、Windows App SDK(旧名称は WinUI 3)に含まれているので、nugetでMicrosoft.WindowsAppSDKを追加すれば使えるようになるはずです。
どうして「はず」なのかといえば、確認するために使った.NET 6なWPFアプリがx86/x64/ARM/ARM64対応のものだったので、Windows App SDKがARMに対応していないというビルドエラーがでて動作確認までに至らなかったからです。
また、時間を見つけて確認してみたいと思います。

なにはともあれ、すごく楽にWindows Runtime APIが使えるようになったので、例えば、Bluetooth関連だとか、カメラデバイス一覧だとかは簡単に取得できますね。

Azure Speech to Textにコミットメントレベル料金プランが登場

docs.microsoft.com

### コミットメントプランとは
コミットメント料金プランって、聞きなれないプラン名ですが、要するに利用時間にかかわらず毎月定額払いの料金プランです。
かといって定額使いたい放題ではなく、定額費用に応じて利用できる時間数がきまっています。

### コミットメントプランの利用時間上限と月額固定費用
Speech to Textの場合、
2,000時間|$1,600
10,000時間|$6,500
50,000時間|$25,000
という金額になります。

### 上限時間を超えたなら
では、上限時間を超えたらどうなるかといえば、コミットメントプランの時間単価での従量課金に移行します。
2,000時間|2,001時間以降は、$0.80/時間
10,000時間|10,001時間以降は、$0.65/時間
50,000時間|50,001時間以降は、$0.50/時間
ある意味安心な料金プランですね。

### Standardな従量課金プランよりお得
Standardプランだと1時間1$なのだいぶお安くなりますね。月何時間使うのかがみえてきたらコミットメントプランへの移行も検討してみるとコストが抑えられるかも。

ソリューションファイルをVisual Studio 2022用に変更する

f:id:hatsune_a:20211221115625p:plain
Visual Studio 2022をインストールすると、Visual Studio 2019で作成したソリューションファイルの右肩には「16」の数字が表示されるようになります。
これを、図の右のように数字がついていないソリューションファイルにするにはどうしたらいいでしょうか。

これは非常に簡単で

  1. Visual Studio 2022でそのソリューションファイルを開く
  2. ソリューションエクスプローラーでソリューションを選択
  3. [ファイル]-[xxxxx.slnの保存]メニューで上書き保存

とすればOKです。

この操作によってソリューションファイルの内容が
f:id:hatsune_a:20211221115934p:plain
から、
f:id:hatsune_a:20211221120208p:plain
に変更になります。

Visual Studio 2022の条件付きコンパイルの設定が素敵すぎる件

まずは、プロジェクトのプロパティの条件付きコンパイルシンボルを見てもらいたいです!
Visualf:id:hatsune_a:20211220135409p:plain
どのソリューション構成の時にどのようなシンボルがあるのか一目瞭然です。
また、ソリューション構成名がデフォルトでシンボルに入るのもいいですね。
.NET Frameworkから.NET 6に移行するとき、コードを変える必要はほぼないのですが、どうしても一部変更したいときようなときは
#if NETCOREAPP
(ここは.NET 6)
#else
(ここは.NET Framework
#endif
のような感じで条件コンパイルが可能です。
便利ですね。

.NET 6でWPFアプリを作成してみる

Visual Studio 2022を使うと、.NET 6でWPFアプリが作成できます。
Visual Studioのプロジェクトでアプリのプロパティを開くと、今までとは雰囲気の違う内容が表示されます。
f:id:hatsune_a:20211220132448p:plain
ターゲットOSや、サポートされているOSバージョンなどの指定ができるのは、XamarinっぽいというかUWPアプリっぽい感じです。
上の例では、Windows 7 SPを最小OSとして、ターゲットOSは10.0.17763.0(1809=Windows 10 October 2018 Updateですね)としています。
10.0.17763.0は、2021年5月11日にサポートが終了しているので、ターゲットは最新のWindows 10バージョンにするか、2022年5月までサポートがある18363でもよいかもしれませんね。