ASP.NET Blazor 怎麼處裡狀態?

關於狀態

其實原則上來說,對於現代的應用程式開發、如果相容於 Cloud 環境/Microservices 等環境的話,您根本不應該將狀態保存在應用程式自身,但這不代表應用程式不處理狀態!注意囉,不管哪一種應用程式,都有(自身的狀態/User 使用者的狀態)需要被保存,最典型的來說(如:login Security)我怎麼知道你 User 目前是否有登入到系統?這是個典型的例子,但即便如此,不代表應用程式要將狀態資訊保存在自身的 Context 環境中,因為應用程式可能所處在一個隨時可橫向擴展 Scale-Out 的環境裡,應用程式自身的 Context 隨時會 Scale-Out/Restart,甚至應用程式自身也不會知道自己會被執行在哪一台(主機/環境)裡。


使用 Redis

使用 Redis 來處理狀態是一個最佳的選擇,它的高效能讓它不僅僅是適合用在分散式運算環境、Cloud/Microservices 等環境中,當然也是 ASP.NET Core 或 Blazor 類型應用程式處裡狀態的首選。

在 ASP.NET MVC 5/ASP.NET Blazor/.NET Core 環境下,同樣可使用 StackExchange.Redis 套件可以使用,程式的撰寫方式也出乎沒有什麼不同,本篇就不再詳述。

一般來說,可以使用如方式;


可使用如下程式碼進行(操作/存取)Redis:


使用 ASP.NET Core 內建的 MemoryCache

在 Blazor 的環境下其實就等同於 ASP.NET Core 的環境,所以同樣具備 MemoryCache,使用方式就是在 Startup 的 ConfigureServices() 裡加入該 Middleware 即可!如下:


不過,即便你要在 Blazor 的應用程式下使用 Redis 當作 SessionState 的保存的儲存體,你也是要開啟 Session 的功能才可以,Blazor 是基於 ASP.NET Core 的應用程式,所以方式與 ASP.NET Core 完全相同,只是 Session 的起用必須同時啟用分散式快取,如下:


使用 MemoryCache 的方式如下,這邊以一個 Controller 為例:


我們可以拿 Blazor 預設樣板中的 Counter 來實驗 Session 的功能,如果有玩過 Blazor 的讀者們應該記得,在 Blazor 的預設樣板裡面,有一個 Counter.cshtml 頁面,而這個頁面有一個 count 數值雖然能夠 +1,但是無法保存下來對嗎?如果我們能將 currentCount 保存在 Session 中,那麼每個 User 就可以在自身的工作階段中保存 & 看到自己的 Click 數目。

但是,遺憾的是,我在這邊遭遇到一個似乎無解的問題,這問題是在 Blazor 的 Hosted in ASP.NET Server 這個樣板中,也就是如果我需要在 Blazor 的 View 上使用 Session 的話,勢必要在『 [YourProjectName].Client 』的專案上透過 DI  的方式注入 IHttpContextAccessor 介面,因此 Counter.cshtml 的程式碼可能會像這樣



但是,這個問題是,這樣得在 [YourProjectName].Client 的專案上安裝『Microsoft.AspNetCore.Http』、『Microsoft.AspNetCore.Http.Abstractions』、『Microsoft.AspNetCore.Http.Feature』這三個套件,可是當在[YourProjectName].Client 的專案裝了三個件後,編譯立即失敗

目前官方的解法也似乎都無效,如果有人有解法也歡迎在底下留言,或者跟我說。


後記:

這一次的 Blazor 的測試還真的是個採坑之旅。


ASP.NET Blazor 系列文章導讀

(一)、ASP.NET Blazor 關鍵報告

(二)、Blazor 怎麼處裡狀態?

(三)、Blazor 怎麼處裡狀態?【保存預設範本的 Count 值】

(四)、Blazor 的 CRUD 應用程式 – Use Entity Framework Core

(五)、Blazor 如何使用自定義的 ApiHostBase?【接續 Clean Architecture 的 API 框架設計 (1)】

(六)、Blazor 如何使用自定義的 ApiHostBase?【接續 Clean Architecture 的 API 框架設計 (2)】

(七)、… 還在想 XDD


References:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?tabs=aspnetcore2x&view=aspnetcore-2.2
https://learn-blazor.com/architecture/dependency-injection/
https://github.com/aspnet/Blazor/issues/1327
https://github.com/aspnet/AspNetCore/issues/5330
https://stackoverflow.com/questions/53817373/how-do-i-access-httpcontext-in-server-side-bazor
https://docs.microsoft.com/zh-tw/aspnet/core/fundamentals/app-state?view=aspnetcore-2.2




關於 Gelis:

資深 .NET 技術顧問

FB 社團 (軟體開發之路):

https://www.facebook.com/groups/361804473860062/

FB 粉絲團 (Gelis 的程式設計訓練營):

https://www.facebook.com/gelis.dev.learning/

我講授過的課程 SlideShare:

https://www.slideshare.net/GelisWu


以下是我經營的項目與內容:

(1). 企業內訓課程

(2). 專業顧問


企業內訓課程:

1. .NET Core 3.1 從入門到進階

先前實體課程連結

2. 跨平台的 Web API Framework 框架設計

先前實體課程連結

3. 決戰 OOAD 系列課程 - 使用 UML

先前實體課程連結

4. 單元測試 UnitTest 與 Moq 物件實務課程

先前實體課程連結

5. 快速開發系列 - C# Project Templates 範本設計

留言

這個網誌中的熱門文章

什麼是 gRPC ?

什麼是 gRPC(二)- 來撰寫第一個 Hello World 吧!

常見的程式碼壞味道(Code Smell or Bad Smell)