共用方式為


狀態管理

提示

此內容節錄自《適用於 ASP NET Web Forms Developers for Azure 的 Blazor》電子書,可以從 .NET Docs 取得,或免費下載可離線閱讀的 PDF。

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover thumbnail.

狀態管理是 Web Forms 應用程式的重要概念,是透過 ViewState、工作階段狀態、應用程式狀態和回傳功能輔助。 架構的這些具狀態功能有助於隱藏應用程式所需的狀態管理,並允許應用程式開發人員專注於提供其功能。 使用 ASP.NET Core 和 Blazor 時,其中一些功能已重新配置,有些則已完全移除。 本章檢閱如何使用 Blazor 中的新功能來維護狀態,並提供相同的功能。

使用 ViewState 要求狀態管理

在 Web Forms 應用程式中討論狀態管理時,許多開發人員都會立即想到 ViewState。 在 Web Forms 中,ViewState 會將大型編碼的文字區塊針對瀏覽器來回傳送,以管理 HTTP 要求之間內容的狀態。 ViewState 欄位可能會因為包含許多元素的頁面內容而超過負荷,且可能會擴充為數 MB 的大小。

透過 Blazor Server,應用程式可與伺服器維持持續連線。 當連線被視為使用中時,應用程式的狀態 (稱為「線路」) 會保留在伺服器記憶體中。 只有在使用者離開應用程式或應用程式中的特定頁面時,才會處置狀態。 使用中元件的所有成員都可以在與伺服器互動之間取得。

此功能有幾個優點:

  • 元件狀態隨手可得,且不會在互動之間重建。
  • 狀態不會傳輸至瀏覽器。

不過,記憶體內的元件狀態持續性有一些缺點需要注意:

  • 如果伺服器在要求之間重新啟動,就會失去狀態。
  • 您的應用程式 Web 伺服器負載平衡解決方案必須包括相黏工作階段,以確保來自相同瀏覽器的所有要求都會返回相同的伺服器。 如果要求進入不同的伺服器,將會失去狀態。
  • 伺服器上的元件狀態持續性可能會導致 Web 伺服器上的記憶體壓力。

基於上述原因,請不要只依賴元件的狀態會駐留在伺服器上的記憶體中。 您的應用程式也應該針對要求之間的資料,包括一些支援的資料存放區。 此策略的一些簡單範例如下:

  • 在購物車應用程式中,將新增至購物車的新項目內容保存在資料庫記錄中。 如果失去伺服器的狀態,您可以從資料庫記錄重新建構該狀態。
  • 在多部分 Web 表單中,您的使用者會預期您的應用程式會記住每個要求之間的值。 將每個使用者貼文之間的資料寫入資料存放區,以便在多部分表單完成時擷取並組合成最終表單回應結構。

如需有關管理 Blazor 應用程式中狀態的其他詳細資料,請參閱 ASP.NET Core Blazor 狀態管理

使用工作階段維護狀態

Web Forms 開發人員可以使用 Microsoft.AspNetCore.Http.ISession 字典物件,維護目前作用中使用者的相關資訊。 將具有字串索引鍵的物件新增至 Session 很容易,而且該物件稍後可在使用者與應用程式的互動期間使用。 為避免管理與 HTTP 的互動,Session 物件可讓您輕鬆地維護狀態。

.NET Framework Session 物件的特徵標記與 ASP.NET Core Session 物件不同。 在決定移轉和使用新的工作階段狀態功能之前,請參考新 ASP.NET Core 工作階段的文件

工作階段可在 ASP.NET Core 和 Blazor Server 中使用,但不建議將其用於取代將資料適當地儲存在資料存放庫中。 如果訪客因為隱私權顧慮而拒絕在應用程式中使用 HTTP Cookie,工作階段狀態也不無法運作。

ASP.NET Core 和工作階段狀態的設定可在 ASP.NET Core 中的工作階段和狀態管理一文中取得。

應用程式狀態

Web Forms 架構中的 Application 物件提供龐大的跨要求存放庫,以便與應用程式範圍設定和狀態互動。 無論提出要求的使用者是誰,應用程式狀態都是儲存所有要求所參考的各種應用程式設定屬性的理想位置。 Application 物件的問題在於資料不會跨多部伺服器保存。 在重新啟動之間會失去應用程式物件的狀態。

如同 Session,建議將資料移至可由多個伺服器執行個體存取的永續性備份存放區。 如果有您想要能夠跨要求和使用者存取的變動性資料,可以將其輕鬆地儲存在可以插入需要此資訊或互動之元件的單一服務中。

要維護應用程式狀態之物件的建構及其耗用量可能類似下列實作:

public class MyApplicationState
{
    public int VisitorCounter { get; private set; } = 0;

    public void IncrementCounter() => VisitorCounter += 1;
}
app.AddSingleton<MyApplicationState>();
@inject MyApplicationState AppState

<label>Total Visitors: @AppState.VisitorCounter</label>

MyApplicationState 物件只會在伺服器上建立一次,而且會在元件標籤中擷取和輸出 VisitorCounter 值。 VisitorCounter 值應該在支援資料存放區中保存並從中擷取,以獲得持久性和可擴縮性。

在瀏覽器中

應用程式資料也可以儲存在用戶端的使用者裝置上,以供稍後使用。 有兩個瀏覽器功能可讓您在使用者瀏覽器的不同範圍內保存資料:

  • localStorage - 範圍限於使用者的整個瀏覽器。 如果重新載入頁面,瀏覽器會關閉後再重新開啟,或是使用相同的 URL 開啟另一個索引標籤,則瀏覽器會提供相同的 localStorage
  • sessionStorage - 範圍限於使用者目前的瀏覽器索引標籤。如果重新載入索引標籤,狀態將會持續。 不過,如果使用者為應用程式開啟另一個索引標籤,或關閉瀏覽器後再重新開啟,就會失去狀態。

您可以撰寫一些自訂的 JavaScript 程式碼來與這些功能互動,或者也有數個 NuGet 套件可供您用來提供此功能。 其中一個套件是 Microsoft.AspNetCore.ProtectedBrowserStorage (英文)。

如需有關使用此套件與 localStoragesessionStorage 互動的指示,請參閱 Blazor 狀態管理一文。