[Asp.Net Core] 為什麼選擇 Blazor Server Side (一) 快速實現圖片驗證碼
關於Blazor
由於在國內, Blazor一點都不普及, 在閱讀此文前, 建議讀者先翻看我之前寫的隨筆, 瞭解Blazor Server Side的特點.
在一段時間內, 我會寫一些解說分析型的 "為什麼選擇 Blazor Server Side" , 在適當的時候再寫快速入門系列.(無論是針對程式設計新學者還是多年經驗人士)
驗證碼
我們很多場合都實現過圖片驗證碼.
圖片驗證碼的主要關鍵是呈現圖片, 需要一個URL, 而這個URL需要傳遞引數以確定顯示什麼東西.
這個驗證碼如何在伺服器儲存, 如何傳遞一個引數公開給客戶端, 還不能讓別人解密這個引數破解驗證碼, 都是麻煩事
這個例子是講述如何用極短的 "單頁" 程式碼, 實現驗證過程.
先上圖:
再上程式碼:
1 @page "/BlazorVerificationCode" 2 3 <p> 4 (Blazor) A sample for how to show verification code and verify it. 5 </p> 6 7 @inject IJSRuntime jsr 8 9 @{ 10 if (imgurl == null) MakeNewImage(); 11 } 12 13 <img style="border:solid 1px #ccc" src="@imgurl" /> 14 <button @onclick="MakeNewImage">Renew</button> 15 <hr /> 16 <div>Type the number in image</div> 17 <EditForm Model="this" OnSubmit="DoCheck"> 18 <input type="text" @bind-value="inp_code" style="padding:5px" /> 19 <button>Check</button> 20 </EditForm> 21 22 @code{ 23 string inp_code; 24 string vericode; 25 string imgurl; 26 27 void DoCheck() 28 { 29 string msg = "You typed a wrong value"; 30 if (inp_code == vericode) 31 msg = "Yes the number is " + vericode; 32 jsr.InvokeAsync<object>("alert", msg); 33 } 34 35 void MakeNewImage() 36 { 37 38 vericode = new Random().Next(100000, 999999).ToString(); 39 40 using SkiaSharp.SKBitmap bmp = new SkiaSharp.SKBitmap(200, 80); 41 42 using (SkiaSharp.SKCanvas canvas = new SkiaSharp.SKCanvas(bmp)) 43 { 44 canvas.Clear(SkiaSharp.SKColors.White); 45 using SkiaSharp.SKPaint skp = new SkiaSharp.SKPaint(); 46 skp.Color = SkiaSharp.SKColors.Red; 47 skp.TextSize = 40; 48 canvas.DrawText(vericode, 30, 55, skp); 49 canvas.Save(); 50 } 51 52 using System.IO.MemoryStream ms = new System.IO.MemoryStream(); 53 using SkiaSharp.SKManagedWStream ws = new SkiaSharp.SKManagedWStream(ms); 54 bmp.Encode(ws, SkiaSharp.SKEncodedImageFormat.Jpeg, 100); 55 56 imgurl = "data:image/jpeg;base64," + Convert.ToBase64String(ms.ToArray()); 57 } 58 59 }
展現效果如下:
下面是解說
整個程式碼只有 60 行.
已經包含了,展示介面, 生成圖片,傳遞和測試驗證碼的各部分.
程式碼先用隨機數確保生成 vericode = new Random().Next(100000, 999999).ToString();
然後根據vericode生成一個圖片, 轉換成base64格式到 imgurl 變數
最後通過 <img style="border:solid 1px #ccc" src="@imgurl" /> 呈現出來.
我上一篇隨筆有介紹, Blazor是'活'的, 是在伺服器上生存著的.
<button @onclick="MakeNewImage">Renew</button> 在伺服器上有活動的instance, 而在客戶端瀏覽器也有'映象副本'
當瀏覽器的'映象副本'被使用者點選後, Blazor就會把事件回傳給伺服器, 觸發伺服器還在執行中的 MakeNewImage
MakeNewImage 會重新生成新的 vericode 與 imgurl , 並且按照Blazor預設行為, 會自動重新Render當前控制元件的內容, 所以 <img> 的 src 會被重新設定到新的imgurl , 展現新的圖片給使用者.
當用戶在 <input type="text" @bind-value="inp_code" style="padding:5px" /> 輸入驗證碼後, Blazor會根據onchange事件, 把value傳送到伺服器, 根據 @bind-value="inp_code" 這個配置, 把值儲存到 inp_code 上.
當 <button>Check</button> 被按下後, OnSubmit="DoCheck" 會觸發, 那麼 DoCheck() 的程式碼, 便可以判斷 inp_code == vericode 是否相同.
這個過程中, 和其他框架做法的最大不同時, Blazor 保持了伺服器程式碼執行的上下文, 因為上下文被保持了, 所以就不需要額外的傳遞了.
這就是為什麼要 為什麼選擇 Blazor Server Side (一) : 使用上下文來節省時間
&n