小窍门
状态管理是 Web 窗体应用程序的关键概念,通过 ViewState、会话状态、应用程序状态和回发功能促进。 框架的这些有状态功能有助于隐藏应用程序所需的状态管理,并允许应用程序开发人员专注于交付其功能。 使用 ASP.NET Core 和 Blazor,其中一些功能已被重新定位,一些功能已被完全删除。 本章介绍如何使用 Blazor 中的新功能维护状态并提供相同的功能。
使用 ViewState 管理请求状态
在 Web 窗体应用程序中讨论状态管理时,许多开发人员将立即想到 ViewState。 在 Web 窗体中,ViewState 通过向浏览器发送大量编码的文本块来管理 HTTP 请求之间的内容状态。 ViewState 字段可能会被包含许多元素的页面内容充斥,并可能增加到几兆字节的大小。
使用 Blazor 服务器时,应用会与服务器保持持续连接。 当连接被视为活动时,应用的状态(称为 线路)保存在服务器内存中。 仅当用户离开应用或应用中的特定页面时,才会释放状态。 活动组件的所有成员在与服务器的交互之间都可用。
此功能有几个优点:
- 组件状态随时可用,并且不会在交互之间重新生成。
- 状态不会传输到浏览器。
但是,内存中组件状态持久性存在一些缺点,需要注意:
- 如果服务器在请求之间重启,状态将丢失。
- 应用程序 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 核心会话的文档 。
会话在 ASP.NET Core 和 Blazor Server 中可用,但为了将数据适当存储在数据存储库中,不建议使用。 如果访问者由于隐私问题而拒绝在应用程序中使用 HTTP Cookie,则会话状态也不起作用。
ASP.NET Core 文章中的会话和状态管理中提供了 ASP.NET 核心和会话状态的配置。
应用程序状态
Application
Web 窗体框架中的对象提供了一个巨大的跨请求存储库,用于与应用程序范围配置和状态交互。 应用程序状态是存储所有请求引用的各种应用程序配置属性的理想位置,无论用户发出请求。
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。
有关使用此包与 localStorage
和 sessionStorage
进行交互的说明,请参阅 Blazor 状态管理 文章。