# 画面設計書 17-BlazorHosted（ASP.NET Core統合）

## 概要

本ドキュメントは、ASP.NET Core上でホストされるBlazorクライアント画面の設計書です。この画面は、ASP.NET CoreサーバーにホストされるBlazor WebAssemblyクライアントとして、SignalRを使用したリアルタイム通信機能をテストするためのアセットです。

### 本画面の処理概要

この画面では、ASP.NET CoreサーバーにホストされたBlazor WebAssemblyクライアントがSignalRハブとの通信を行います。Chatページがルート画面として設定されており、初回レンダリング時にSignalRTestを実行してサーバーとのリアルタイム通信をテストします。

**業務上の目的・背景**：本画面は、ASP.NET CoreとBlazor WebAssemblyの統合テストを目的としています。Blazorアプリケーションがサーバーサイドのリソース（SignalRハブなど）と連携する際の動作を検証します。WasmEnableThreadsが有効化されており、マルチスレッド環境でのBlazor動作も確認できます。チャットアプリケーションのような双方向通信を必要とするシナリオのテストに使用されます。

**画面へのアクセス方法**：ASP.NET Coreサーバーを起動後、`/blazorclient/`パスにアクセスすることで画面が表示されます。base hrefが"/blazorclient/"に設定されているため、このパスが基準になります。

**主要な操作・処理内容**：
1. ページロード時にBlazor WebAssemblyランタイムを初期化
2. Appコンポーネントをマウント
3. ルーターがChatページ（/）を表示
4. Chat.razorのOnAfterRenderAsyncでSignalRTestを実行
5. SignalRハブとの通信テストを実行
6. 結果に応じて終了コードを出力

**画面遷移**：このアプリケーションはChatページ（/）のみの単一画面構成です。

**権限による表示制御**：認証・権限機能は実装されていません。テスト用アセットのため、すべての機能が実行可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Mono | 主機能 | ASP.NET Core上でホストされるBlazorランタイム実行 |
| 59 | WebAssembly Workload | 主機能 | Blazor WebAssemblyアプリケーションのビルドと実行をサポート |
| 34 | Microsoft.Extensions.Hosting | 補助機能 | ASP.NET Core汎用ホスト機能との統合 |
| 14 | System.Net.WebSockets | 補助機能 | SignalRによるWebSocket通信 |

## 画面種別

エントリーポイント画面（ASP.NET Core統合Blazor WebAssembly）

## URL/ルーティング

- パス: `/blazorclient/index.html` または `/blazorclient/`
- テンプレートファイル: `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/wwwroot/index.html`

## 入出力項目

| 項目名 | 入力/出力 | 型 | 説明 |
|--------|----------|-----|------|
| なし | - | - | エントリーポイントのため直接の入出力項目はなし |

## 表示項目

| 項目名 | 説明 | 初期値 |
|--------|------|--------|
| ローディング表示 | アプリ読み込み中に表示されるテキスト | Loading... |
| エラーUI | 未処理例外発生時に表示されるエラーパネル | 非表示 |
| チャットルーム | Chatページの見出し | Chat Room |

## イベント仕様

### 1-ページロード時のBlazorアプリ初期化

**トリガー**: ブラウザがindex.htmlを読み込み完了

**処理フロー**:
1. div#appに"Loading..."が表示される
2. blazor.webassembly.jsスクリプトが実行される
3. WebAssemblyランタイムが初期化される
4. Program.csのMainメソッドが実行される
5. Appコンポーネントが#appにマウントされる
6. ルーターがChatページを表示

**結果**: Chatページが表示される

### 2-Chat画面の初回レンダリング時

**トリガー**: Chatページの初回レンダリング完了（OnAfterRenderAsync, firstRender=true）

**処理フロー**:
1. ShouldRender()でレンダリング可否を確認（デバッグログ出力）
2. OnAfterRenderAsync()でfirstRenderを確認
3. SignalRTestインスタンスを作成
4. NavigationManager.BaseUriとUriを引数にRun()を実行
5. SignalRハブとの通信テストを実行
6. 結果に応じて"WASM EXIT {code}"を出力

**結果**: SignalRテストが実行され、結果がTestOutputに出力される

### 3-エラー発生時

**トリガー**: Blazorアプリケーション内で未処理例外が発生

**処理フロー**:
1. エラーUI（div#blazor-error-ui）が表示される
2. ユーザーはReloadリンクでページ再読み込み可能

**結果**: エラー情報がユーザーに表示される

## データベース更新仕様

本画面ではデータベース操作は行いません。

## メッセージ仕様

| メッセージ種別 | 表示条件 | メッセージ内容 |
|---------------|---------|---------------|
| ローディング | 初期読み込み時 | "Loading..." |
| エラーUI | 未処理例外発生時 | "An unhandled error has occurred." |
| テスト出力 | ShouldRender実行時 | "ShouldRender = {bool}" |
| テスト出力 | テスト開始時 | "SignalRTest is started on CurrentManagedThreadId={id}" |
| テスト出力 | テスト完了時 | "SignalRTest finished with code {result}. WASM EXIT {result}" |
| テスト出力 | テスト失敗時 | "SignalRTest failed with exception {ex}. WASM EXIT -1" |

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| WebAssembly読み込み失敗 | "Loading..."が表示されたまま |
| SignalRテスト例外 | TestOutputに例外情報を出力し、WASM EXIT -1 |
| 未処理例外 | blazor-error-uiが表示される |

## 備考

- 本画面はASP.NET Core上でホストされるBlazor WebAssemblyのテスト用アセットです
- WasmEnableThreadsが有効化されており、マルチスレッド環境で動作します
- StaticWebAssetBasePathが"blazorclient"に設定されています
- Sharedプロジェクトを参照してSignalRTest機能を使用します
- ShouldRenderのオーバーライドはデバッグ用（issue #96546の調査用）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

SignalRTestクラスとBlazorコンポーネントの連携を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Chat.razor | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Pages/Chat.razor` | SignalRTestの呼び出しとライフサイクルメソッドの使用 |

**読解のコツ**: BlazorのOnAfterRenderAsync()はコンポーネントがDOMにレンダリングされた後に呼ばれます。firstRenderフラグで初回のみ処理を実行します。

#### Step 2: エントリーポイントを理解する

HTMLシェルの構成を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.html | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/wwwroot/index.html` | base hrefが/blazorclient/に設定されている |

**主要処理フロー**:
1. **9行目**: base href="/blazorclient/"でルーティングのベースパスを設定
2. **14行目**: div#appに"Loading..."表示
3. **16-19行目**: エラーUI
4. **21行目**: blazor.webassembly.jsの読み込み

#### Step 3: ルートコンポーネントを理解する

App.razorとChatページを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Chat.razor | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Pages/Chat.razor` | @page "/"でルートに配置、SignalRTest実行 |

**主要処理フロー**:
- **1行目**: `@page "/"`でルートURLにマッピング
- **2行目**: NavigationManagerを注入
- **4行目**: h1で"Chat Room"を表示
- **6行目**: SignalRTestインスタンスを保持
- **10-15行目**: ShouldRender()でデバッグログ出力
- **17-32行目**: OnAfterRenderAsync()でSignalRテストを実行

#### Step 4: C#起動コードを理解する

Program.csの構成を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Program.cs | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Program.cs` | WebAssemblyHostBuilderの構成 |

**主要処理フロー**:
- **8行目**: WebAssemblyHostBuilder.CreateDefault()
- **9行目**: Appコンポーネントを#appにマウント
- **10行目**: HeadOutletをhead::afterにマウント
- **11行目**: HttpClientをスコープサービスとして登録
- **13行目**: RunAsync().ConfigureAwait(false)でアプリケーション起動

### プログラム呼び出し階層図

```
index.html (HTMLシェル)
    │
    ├─ div#app → "Loading..."
    │
    └─ blazor.webassembly.js
           │
           └─ Program.Main() [C#]
                  │
                  ├─ WebAssemblyHostBuilder.CreateDefault()
                  │
                  ├─ RootComponents.Add<App>("#app")
                  │
                  └─ builder.Build().RunAsync()
                         │
                         └─ App.razor
                                │
                                └─ Router → Chat.razor (@page "/")
                                       │
                                       ├─ ShouldRender() → ログ出力
                                       │
                                       └─ OnAfterRenderAsync(firstRender=true)
                                              │
                                              ├─ SignalRTest test = new()
                                              │
                                              ├─ test.Run(BaseUri, Uri)
                                              │      │
                                              │      └─ SignalRハブ通信
                                              │
                                              └─ TestOutput.WriteLine("WASM EXIT {result}")
```

### データフロー図

```
[入力]                      [処理]                           [出力]

ブラウザリクエスト        HTMLシェル                    Blazor SPA
/blazorclient/  ───▶    index.html               ───▶    Chat.razor
                              │
                              ▼
                    blazor.webassembly.js
                              │
                              ▼
                    Program.Main() [C#]
                              │
                              ▼
                    Router → Chat (@page "/")
                              │
                              ▼
                    OnAfterRenderAsync()
                              │
                              ▼
                    SignalRTest.Run()
                              │
                              ▼
                    SignalRハブ通信
                              │
                              ▼
                    TestOutput ("WASM EXIT {code}")
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.html | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/wwwroot/index.html` | テンプレート | Blazor WebAssemblyのHTMLシェル |
| Program.cs | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Program.cs` | ソース | アプリケーション起動とDI構成 |
| App.razor | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/App.razor` | ソース | ルートコンポーネント |
| Chat.razor | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Pages/Chat.razor` | ソース | チャットページ、SignalRTest実行 |
| MainLayout.razor | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/Layout/MainLayout.razor` | ソース | レイアウトコンポーネント |
| _Imports.razor | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/_Imports.razor` | ソース | グローバルusing宣言 |
| BlazorClient.csproj | `src/mono/wasm/testassets/WasmOnAspNetCore/BlazorClient/BlazorClient.csproj` | 設定 | プロジェクト設定（スレッド有効化） |
