深入淺出Blazor webassembly之異常錯誤顯示
Blazor wasm 原生模版中沒有提供對End user友好的異常處理機制. 一般情況下我們都需要自行實現一套自己的異常處理機制
==============================
原生的異常處理機制
==============================
Fetch.razor 的初始化代碼, 加載一個不存在的json 文件, 導致程序異常, 未做特殊處理的情況.
protected override async Task OnInitializedAsync() { forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/not_found.json"); }

==============================
簡單的JS alert處理機制
==============================
注入 IJSRuntime 調用 js alert 函數來處理異常, 對于End user 稍微好了一些, 但還是不夠友好.
[Inject] IJSRuntime Js { get; set; } protected override async Task OnInitializedAsync() { try { forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/not_found.json"); } catch (Exception ex) { await Js.InvokeVoidAsync("alert", ex.Message); } }

==============================
自定義全局異常處理機制: Layout中內置一個全局的ErrorComponent
==============================
1. 聲明一個 IErrorComponent 接口
namespace WebApplication2 { public interface IErrorComponent { void ShowError(string title, string message); } }
2. MainLayout.razor 實現 IErrorComponent接口, 并提供顯示和關閉Error
@inherits LayoutComponentBase @implements IErrorComponent <div class="page"> <div class="sidebar"> <NavMenu /> </div> <div class="main"> <div class="top-row px-4"> <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a> </div> <div class="content px-4"> @if (_IsErrorActive) { <div class="alert alert-danger" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close1" @onclick="HideError"> <span aria-hidden="true">×</span> </button> </div> <h3>@_Title</h3> <p>@_Message</p> } <CascadingValue Value="this" Name="ErrorComponent"> @Body </CascadingValue> </div> </div> </div> @code{ bool _IsErrorActive; String _Title; String _Message; public void ShowError(string title, string message) { this._IsErrorActive = true; this._Title = title; this._Message = message; StateHasChanged(); } private void HideError() { this._IsErrorActive = false; } }
改造之前, content 部分非常簡單, 代碼見下, 改造之后, 在@Body 加了顯示 error message的 alert 卡片.
<div class="content px-4"> @Body </div>
另外, 使用 CascadingValue 組件將 MainLayout 作為 IErrorComponent 的實例傳導到各個頁面中.
3. FetchData.razor 文件中, 使用 CascadingParameter 承接 IErrorComponent 實例, 并在異常點使用該實例顯示出來.
[CascadingParameter(Name = "ErrorComponent")] IErrorComponent _ErrorComponent { get; set; } protected override async Task OnInitializedAsync() { try { forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/not_found.json"); } catch (Exception ex) { _ErrorComponent.ShowError(ex.Message, ex.StackTrace); } }
效果圖:

==============================
參考
==============================
https://nightbaker.github.io/gitflow/azure/piplines/2020/01/22/blazor-error-component/
https://nightbaker.github.io/blazor/exception/2021/08/11/throws-exceptions-to-blazor/

浙公網安備 33010602011771號