ASP.Net 状态管理技术






2.23/5 (11投票s)
2007 年 1 月 17 日
9分钟阅读

100755
ASP.Net 状态管理技术
引言
本文讨论了使用 ASP.NET 开发的 Web 应用程序的各种状态管理选项。通常,Web 应用程序基于无状态 HTTP 协议,该协议不保留有关用户请求的任何信息。在典型的客户端和服务器使用 HTTP 协议通信中,每次请求页面时都会创建页面。当开发提供自定义内容并“记住”用户的应用程序时,开发人员被迫实现各种状态管理技术。
在这里,我们为 ASP.NET 开发人员提供了在应用程序中实现状态管理技术的各种选项。广义上,我们可以将状态管理技术分为客户端状态管理或服务器端状态管理。每种技术都有其优缺点。让我们从探索客户端状态管理选项开始。
客户端状态管理选项
ASP.NET 提供了各种客户端状态管理选项,如 Cookie、QueryStrings (URL)、隐藏字段、ViewState 和 Control State (ASP.NET 2.0)。让我们讨论每个客户端状态管理选项。
在实现客户端状态管理选项时应考虑带宽,因为它们涉及每次往返服务器。示例:每次页面请求时,Cookie 都会在客户端和服务器之间交换。
Cookie
Cookie 是存储在用户计算机上的小段文本。通常,信息以名称-值对的形式存储。网站使用 Cookie 来跟踪访问者。每当用户访问网站时,都会从用户机器检索 Cookie,并帮助识别用户。
让我们看一个使用 Cookie 自定义网页的示例。
if (Request.Cookies["UserId"] != null)
lbMessage.text = "Dear" + Request.Cookies["UserId"].Value +
", Welcome to our website!";
else
lbMessage.text = "Guest,welcome to our website!";
//If you want to store client's information use the below code
Response.Cookies["UserId"].Value=username;
优点
- 简单
缺点
- Cookie 可以在用户浏览器上禁用
- Cookie 随每个 HTTP 请求/响应传输,导致带宽开销
- 不适用于敏感数据
隐藏字段
隐藏字段用于在页面级别存储数据。顾名思义,这些字段不会由浏览器渲染。它就像一个标准控件,您可以为其设置属性。每当页面提交到服务器时,隐藏字段的值也会随页面上的其他控件一起发布到服务器。现在,所有 asp.net Web 控件都具有以视图状态形式存在的内置状态管理功能,以及 asp.net 2.0 控件状态中的新功能,隐藏字段的功能似乎是多余的。我们仍然可以使用它来存储无关紧要的数据。我们可以使用以下语法在 ASP.NET 页面中使用隐藏字段
protected System.Web.UI.HtmlControls.HtmlInputHidden Hidden1;
//为隐藏字段赋值
Hidden1.Value="创建隐藏字段";
//检索值
string str=Hidden1.Value;
优点
- 易于实现页面特定数据
- 可以存储少量数据,因此占用空间较小。
缺点
- 隐藏字段值在通过网络传输时可能会被拦截(清晰可见)
视图状态
视图状态可用于存储单个用户的状态信息。视图状态是 Web 控件中内置的功能,用于在页面回发之间持久化数据。您可以使用 EnableViewState 属性为每个控件打开/关闭视图状态。默认情况下,EnableViewState 属性将设置为 true。视图状态机制会带来性能开销。页面上所有控件的视图状态信息将在每次回发时提交到服务器。为了减少性能损失,请禁用所有不需要状态的控件的视图状态。(数据网格通常不需要维护状态)。您还可以通过在 @page 指令中添加 EnableViewState=false 来禁用整个页面的视图状态。视图状态数据以二进制 Base64 编码,这会增加大约 30% 的开销。必须注意确保页面的视图状态大小较小。视图状态可以使用 ASP.NET 网页中的以下语法。
// Add item to ViewState
ViewState["myviewstate"] = myValue;
//Reading items from ViewState
Response.Write(ViewState["myviewstate"]);
优点
- 简单的页面级别数据
- 加密
- 可以在控件级别设置
缺点
- 使页面笨重
查询字符串
查询字符串通常用于将信息从一个页面发送到另一个页面。它们以纯文本形式与 URL 一起传递。现在,asp.net 2.0 中恢复了跨页面发布功能,查询字符串似乎是多余的。大多数浏览器对 URL 长度限制为 255 个字符。我们只能使用查询字符串传递少量数据。由于查询字符串以纯文本形式发送,我们也可以加密查询值。另外,请记住,URL 中无效的字符必须使用 Server.UrlEncode 进行编码。
假设我们有一个包含产品列表的数据网格,以及网格中指向产品详细信息页面的超链接,这将是查询字符串的理想用途,将产品 ID 包含在指向产品详细信息页面的链接的查询字符串中(例如,productdetails.aspx?productid=4)。
请求产品详细信息页面时,可以使用以下代码获取产品信息
string productid;
productid=Request.Params["productid"];
优点
- 易于实施
缺点
- 人类可读
- 客户端浏览器对 URL 长度的限制
- 跨页功能使其多余
- 最终用户易于修改
控制状态
控件状态是 ASP.NET 2.0 中的一种新机制,它解决了视图状态的一些缺点。控件状态可用于在回发之间存储关键的私有信息。控件状态是为控件保留的另一种状态容器,用于维护其核心行为功能,而视图状态仅包含用于维护控件内容(UI)的状态。控件状态与视图状态共享相同的内存数据结构。即使控件的视图状态被禁用,控件状态也可以传播。例如,ASP.NET 2.0 中的新控件 Grid View 有效地利用控件状态来维护其核心行为在回发之间所需的状态。当我们禁用 Grid View 或整个页面的视图状态时,Grid View 不会受到任何影响
服务器端状态管理
顾名思义,状态信息将保留在服务器上。Application、Session、Cache 和 Database 是在服务器上存储状态的不同机制。
必须注意节约服务器资源。对于拥有大量并发用户的高流量网站,使用会话对象进行状态管理可能会给服务器带来负载,导致性能下降
Application 对象
Application 对象用于存储在整个应用程序中可见并跨多个用户会话共享的数据。需要在应用程序整个生命周期内持久化的数据应存储在 Application 对象中。
在经典 ASP 中,应用程序对象用于存储连接字符串。它是存储不经常更改的数据的好地方。我们应该只在 application_Onstart 事件 (global.asax) 或 application.lock 事件中写入应用程序变量,以避免数据冲突。以下代码示例给出了一个想法
Application.Lock();
Application["mydata"]="mydata";
Application.UnLock();
Session 对象
Session 对象用于存储每个客户端特定的状态信息。它特定于特定用户。会话数据在用户会话期间持续存在,您可以通过不同方式将会话数据存储在 Web 服务器上。可以使用应用程序的 web.config 文件中的 <session State> 部分配置会话状态。配置信息
<sessionState mode = <"inproc" | "sqlserver" | "stateserver">
cookieless = <"true" | "false">
timeout = <positive integer indicating the session timeout in minutes>
sqlconnectionstring =
<SQL connection string that is only used in the SQLServer mode>
server =
<The server name that is only required when the mode is State Server>
port =
<The port number that is only required when the mode is State Server>
模式
此设置支持三个选项。它们是 InProc、SQLServer 和 State Server无 Cookie
此设置采用布尔值 true 或 false,指示会话是否是无 Cookie 的。Timeout
这表示会话超时值(以分钟为单位)。这是用户会话处于活动状态的持续时间。请注意,会话超时是一个滑动值;默认会话超时值为 20 分钟SqlConnectionString
这标识了用于模式 SQLServer 的数据库连接字符串。服务器
在进程外模式 State Server 中,它指定运行所需 Windows NT 服务 aspnet_state 的服务器。端口
这标识了与模式 State Server 的服务器设置对应的端口号。请注意,端口是唯一标识在网络上运行的进程的无符号整数。您可以使用 EnableSessionState 属性禁用页面的会话。您可以通过在 web.config 文件中设置 mode=off 来禁用整个应用程序的会话,以减少整个应用程序的开销。 ASP.NET 中的会话状态可以根据各种参数(包括可伸缩性、可维护性和可用性)以不同方式配置- 进程内模式(内存中)- 状态信息存储在 Web 服务器的内存中
- 进程外模式 - 会话状态保存在名为 aspnet_state.exe 的进程中,该进程作为 Windows 服务运行。
- 数据库模式 - 会话状态保存在 SQL Server 数据库中。
进程内模式
此模式适用于可以托管在单个服务器上的小型应用程序。此模型是存储会话特定信息的最常见和默认方法。会话数据存储在本地 Web 服务器的内存中配置信息
<sessionState mode="Inproc"
sqlConnectionString="data source=server;
user id=freelance;password=freelance"
cookieless="false" timeout="20" />
优点
- 最快的模式
- 简单配置
缺点
- 如果工作进程或应用程序域回收,会话数据将丢失
- 不适用于 Web 园和 Web 场
进程外会话模式(状态服务器模式)
此模式是可伸缩和高可用应用程序的理想选择。会话状态保存在名为 aspnet_state.exe 的进程中,该进程作为 Windows 服务运行,默认情况下侦听 TCP 端口 42424。您可以使用服务 MMC 管理单元或通过从命令行运行以下 net 命令来调用状态服务。
Net start aspnet_state
配置信息
<sessionState mode="StateServer"
StateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;
user id=freelance; password=freelance"
cookieless="false" timeout="20"/>
优点
- 会话数据在应用程序域回收后持久化。这是通过使用单独的工作进程来维护状态实现的
缺点
- 需要序列化数据
SQL 支持的会话状态
ASP.NET 会话也可以存储在 SQL Server 数据库中。在 SQL Server 中存储会话提供了弹性,可以为大型 Web 场提供跨 IIS 重启持久化的会话。基于 SQL 的会话状态使用 aspnet_regsql.exe 配置。此实用程序位于 .NET Framework 的安装目录 C:\<windows>\microsoft.net\framework\<version> 中。运行此实用程序将创建一个管理会话状态的数据库。配置信息
<sessionState mode="SQLServer"
sqlConnectionString="data source=server;user id=freelance;password=freelance"
cookieless="false" timeout="20" />
优点
- 支持 Web 场和 Web 园配置
- 当会话在不同的服务器上维护时,会话状态在应用程序域回收甚至 IIS 重启后仍会持久化。
缺点
- 需要对象的序列化。客户端和服务器端管理技术的选择取决于各种因素,包括可用的服务器资源、可伸缩性和性能。我们必须利用客户端和服务器端状态管理选项来构建可伸缩的应用程序。在利用客户端状态选项时,请确保在页面请求之间交换少量无关紧要的信息。在利用服务器端状态选项时,应评估各种参数,包括应用程序的大小、可靠性和健壮性。应用程序越小,进程内是更好的选择。在使用状态服务器和基于数据库的会话状态时,我们应该考虑序列化和反序列化对象所涉及的开销。应用程序状态应该严格使用。
- 与进程内相比,进程外模式提供更慢的访问
- 支持 Web 场和 Web 园配置
- 编码视图状态值的开销
- 不适用于敏感数据