MacでBlazorServer使ってみる


はじめに

会社でBlazor開発をすることになったが家にMacBookしかなかったので、
作業概要を備忘録として残します。

環境

  • macOS Big Sur 11.5.2
  • dotnet 5.0
  • Docker for desktop
  • SQLServer
  • Homebrew
  • VsCode

※ VisualStudio for Macは有料だったので使わない。
※ Homebrew,VsCode,Monoの環境構築はすでに終わっていたので省く

環境構築

Docker for desktop

  • Homebrewからインストール
  • インストールしたら、Lanchpadからアイコン探して実行
    ※ docker-composeもセットで入る
$ brew install docker
$ brew cask install docker

SQLServer(Dockerコンテナ)

docker-compose.yml
version: '3'

services:
    mssql:
      image: mcr.microsoft.com/mssql/server:2019-latest
      container_name: mssql2019
      environment:
        - MSSQL_SA_PASSWORD=[password]
        - ACCEPT_EULA=Y
        - MSSQL_PID=Express
        - MSSQL_COLLATION=Japanese_CI_AS
      hostname: db-server
      restart: always
      ports:
        - 1433:1433
      volumes:
        - ./log:/var/opt/mssql/log
        - ./data:/var/opt/mssql/data
  • 下記のコマンドでコンテナ起動
$ cd [docker-compose.ymlのあるディレクトリ]
$ docker-compose up -d

BlazorServerアプリの作成

$ dotnet new blazorserver -o TestBlazor --no-https
# projectフォルダへ移動
$ cd TestBlazor

Blazorアプリのカスタマイズ(tips集)

DBContextについて

appsettings.json
"ConnectionStrings": {
    "MyDbContext": "Persist Security Info=False;User ID=sa;Password=[自分で決めたpass];Initial Catalog=[自分で決めたDB名];Server=localhost"
  }
MyDbContext.cs
public class MyDbContext : DbContext
{
    public MyDbContext (DbContextOptions<MyDbContext> options) : base (options) { }
    public DbSet<Book> Books { get; set; }
}
Startup.cs
// 下記をサービスのところに追加
services.AddDbContextFactory<MyDbContext> (options =>
  options.UseSqlServer (Configuration.GetConnectionString ("MyDbContext"))
);
  • 各所でのContextの使い方は下記
Index.razor
@page "/"
@inject IDbContextFactory<MyDbContext> DbFactory

@teststr

<p>@_surnameMessage</p>

@code {
    private string teststr;

    protected async override Task OnInitializedAsync()
    {
        using (var context = DbFactory.CreateDbContext())
        {
            // 処理
            teststr = context.Books.FirstOrDefault(b => b.ID == 1);
        }
    }
}

sessionについて

  • 公式サイト 
  • https://docs.microsoft.com/ja-jp/aspnet/core/blazor/state-management?view=aspnetcore-5.0&pivots=server
  • ProtectedSessionStorageを使えと書かれている
    • mvcのときみたいにserviceにaddsessionを書かなくてもセッションは使える模様
    • (ServerPrerenderedの場合)OnInitializedAsyncでは呼び出せないので注意
    • Loading処理かいてOnAfterRenderAsyncで呼び出すかプリレンダリングやめるかで回避できる
  • 下記が例、Counterのページで再読み込みしてもクリックの回数がリセットされない
Counter.razor
@page "/counter"
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedLocalStorage ProtectedLocalStore

@if (isConnected)
{
    <p>Current count: <strong>@currentCount</strong></p>
    <button @onclick="IncrementCount">Increment</button>
}
else
{
    <p>Loading...</p>
}

@code {
    private int currentCount;
    private bool isConnected;// Sessionからデータ取得できたかどうか

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {// 初回読み込みのみ実行
            isConnected = true;
            // OnInitializedAsyncでは呼び出せない
            var result = await ProtectedLocalStore.GetAsync<int>("count");
            currentCount = result.Success ? result.Value : 0;
            StateHasChanged();
        }
    }

    private async Task IncrementCount()
    {
        currentCount++;
        await ProtectedLocalStore.SetAsync("count", currentCount);
    }
}