管理状态
超文本传输协议(HTTP)是一种无状态协议。当客户端从服务器断开连接时,ASP.NET 引擎将丢弃页面对象。这样一来,每个 Web 应用程序能够扩展到同时用于大量请求,但是不会耗尽服务器内存。
然而,需要有一些技术来存储各个请求之间的信息并在需要时取回。这个信息则称为状态,即所有控件的当前值和在当前会话中当前用户使用的变量。
ASP.NET 管理四种状态:
- 视图状态
- 控制状态
- 会话状态
- 应用程序状态
视图状态
视图状态是页面及其所有控件的状态。它通过 ASP.NET 框架的反馈保持不变。
当一个页面被发送回客户端,这些页面变化的属性及其控件是确定的,并存储在名为 _VIEWSTATE 的一个隐藏输入字段的值内。当页面被再次回发时,_VIEWSTATE 字段随 HTTP 请求被发送到服务器。
视图状态可以对以下内容启用或者禁用:
- 整个应用程序:设置 web.config 文件中 部分的 EnableViewState 属性。
- 一个页面:设置页面指令的 EnableViewState 属性为 <%@ Page Language=”C#” EnableViewState=”false” %>
- 一个控件:设置控件 .EnableViewState 属性。
它通过使用视图状态对象,该对象是由被一组视图状态项目定义的 StateBag 类别定义的。该 StateBag 是一种数据结构,包含属性值对并被存储为与对象相关联的字符串。
StateBag 类具有以下属性:
Item(name) | 具有指定名称的视图状态的值,是 StateBag 的默认属性。 |
Count | 状态集合中的项目名称。 |
Keys | 集合中所有项目的密钥集合。 |
Values | 集合中所有项目的值的集合。 |
StateBag 类具有以下方法:
Add(name, value) | 添加一个项目到视图状态集合,更新现有项目。 |
Clear | 移除集合中所有项目。 |
Equals(Object) | 确定指定的对象是否等于当前对象。 |
Finalize | 允许释放资源并执行其他清理操作。 |
GetEnumerator | 返回存储在 StateBag 对象中重复的 StateItem 对象的密钥/值对的计数器。 |
GetType | 获取当前实例的类型。 |
IsItemDirty | 检查存储在 StateBag 对象以确认其是否已被修改。 |
Remove(name) | 移除制定项目。 |
SetDirty | 设置 StateBag 对象的状态以及每个由其包含的 StateItem 对象的 Dirty 属性。 |
SetItemDirty | 为在 StateBag 对象中的指定 StateItem 对象设置 Dirty 属性。 |
ToString | 返回代表状态包对象的字符串。 |
实例
以下实例说明了存储视图状态的字符串的概念。
让我们保持一个计数器,通过点击页面上的一个按钮,该计数器能够在每次页面被调回时递增。标签控件显示计数器的值。
标记文件代码如下所示:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="statedemo._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.zzvips.com/uploads/allimg/cd5uokppnor" > <head runat="server"> <title> Untitled Page </title> </head> <body> <form id="form1" runat="server"> <div> <h3>View State demo</h3> Page Counter: <asp:Label ID="lblCounter" runat="server" /> <asp:Button ID="btnIncrement" runat="server" Text="Add Count" onclick="btnIncrement_Click" /> </div> </form> </body> </html>该实例的后台代码文件如下所示:
public partial class _Default : System.Web.UI.Page { public int counter { get { if (ViewState["pcounter"] != null) { return ((int)ViewState["pcounter"]); } else { return 0; } } set { ViewState["pcounter"] = value; } } protected void Page_Load(object sender, EventArgs e) { lblCounter.Text = counter.ToString(); counter++; } }它将会生成以下结果:
以上代码只存储在会话词典对象中的字符串,但是,它可以存储所有原始数据类型和由原始数据类型组成的阵列,DataSet, DataTable, HashTable, 和图像对象,以及继承 ISerializable 对象的任意用户定义的类。
实例
以下实例说明了存储会话状态的概念。在页面上有两个按钮:输入字符串的文本框按钮和显示从最后一个会话中存储的文本的标签按钮。标记文件代码如下所示:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.zzvips.com/uploads/allimg/cd5uokppnor" > <head runat="server"> <title> Untitled Page </title> </head> <body> <form id="form1" runat="server"> <div> <table style=""> <tr> <td style=""> <asp:Label ID="lblstr" runat="server" Text="Enter a String" style=""> </asp:Label> </td> <td style=""> <asp:TextBox ID="txtstr" runat="server" style=""> </asp:TextBox> </td> </tr> <tr> <td style=""> </td> <td style=""> </td> </tr> <tr> <td style=""> <asp:Button ID="btnnrm" runat="server" Text="No action button" style="" /> </td> <td style=""> <asp:Button ID="btnstr" runat="server" OnClick="btnstr_Click" Text="Submit the String" /> </td> </tr> <tr> <td style=""> </td> <td style=""> </td> </tr> <tr> <td style=""> <asp:Label ID="lblsession" runat="server" style="" > </asp:Label> </td> <td style=""> </td> </tr> <tr> <td style=""> <asp:Label ID="lblshstr" runat="server"> </asp:Label> </td> <td style=""> </td> </tr> </table> </div> </form> </body> </html>在设计视图中应有如下显示:
执行文件并观察其如何运行: