在開發系統時,紀錄是一件很重要的事,前面都沒有提到,筆者在最近才想到這點,所以就來實作吧!
由於筆者用的是 Blazor Server,官方文件提供的只有 Blazor WebAssembly 的做法,所以先來試試看後者。
首先打開之前建立的 BlazorWasm 專案,在Counter.razor
加入@using Microsoft.Extensions.Logging;
及注入服務@inject ILogger<Counter> logger;
,接著在原本的IncrementCount()
內加入要提示的訊息,這邊用的是LogWarning()
,除此之外還有LogCritical
、LogDebug
、LogError
等等可以使用。
@page "/counter"
@using Microsoft.Extensions.Logging;
@inject ILogger<Counter> logger;
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
logger.LogWarning("有人點擊我了!");
currentCount++;
}
}
接著將啟動專案改成 BlazorWasm 專案,啟動後前往 Counter 頁面,點擊按鈕後,按下 F12 切換到 Console 頁籤,可以看到顯示了我們定義的訊息。
在 Blazor WebAssembly 這麼簡單,那在 Blazor Server 也是一樣嗎?
可惜的是 Blazor Server 並不支援這樣的作法,目前只能用IJSRuntime
的方式呼叫瀏覽器的console.log
提示訊息,想要有不同層級的訊息也必須自己客製化。
我們切回 Blazor Server 專案,在JsInteropClasses
加入ConsoleLog()
方法,裡面做的事情就只有呼叫console.log()
public async Task ConsoleLog(string message)
{
await js.InvokeVoidAsync("console.log", message);
}
接著在Blog.razor.cs
覆寫OnAfterRenderAsync()
,在裡面呼叫ConsoleLog()
。
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await jsClass.ConsoleLog("這是Blazor Server的console.log訊息");
}
之所以不寫在OnInitializedAsync()
是因為我們採用預先渲染(pre-render)的方式,此時的 JavaScript 還沒準備好,如果在OnInitializedAsync()
呼叫,會發生下圖的錯誤。
要是一定要在OnInitializedAsync()
呼叫的話,可以去_Host.cshtml
將<component>
的render-mode
屬性從ServerPrerendered
改為Server
。
Server 的render-mode
分為三種:Static
、Server
及ServerPrerendered
,第一種速度最快,將全部 Component都轉變為靜態 HTML 檔案;第二種最慢,會先將一種標記傳出,等到使用者啟動該 Component 後才會真的渲染成 HTML 檔案;第三種是折衷方案,先把 Component 變成靜態 HTML 檔案但沒有互動功能,等到使用者啟動該 Component 後才會通知 Server 將功能補上。
這也是為什麼render-mode
改成Server
才有效的原因,因為此時的ConsoleLog()
還沒轉成 JavaScript 檔案。
Ref:ASP.NET Core Blazor logging
Ref:How can I write into the browser´s console via Blazor WebAssembly?
Ref:Blazor Server
Ref:What's the difference between RenderMode.Server and RenderMode.ServerPrerendered in blazor?
Ref:RenderMode Enum