Asp.net 简明教程
ASP.NET - Managing State
超文本传输协议 (HTTP) 是一个无状态协议。当客户端与服务器断开连接时,ASP.NET 引擎将放弃页面对象。通过这种方式,每个 Web 应用程序可以扩展为同时处理大量请求,而不会耗尽服务器内存。
但是,需要有一些技术在请求之间存储信息并在需要时检索它。此信息,即当前用户在当前会话中所有控件和变量的当前值,称为状态。
ASP.NET 管理四种类型的状态:
-
View State
-
Control State
-
Session State
-
Application State
View State
视图状态是页面及其所有控件的状态。它由 ASP.NET 框架在提交后自动维护。
当页面发送回客户端时,确定页面及其控件的属性中的更改并存储在名为 _VIEWSTATE 的隐藏输入字段的值中。当再次提交页面时,_VIEWSTATE 字段会与 HTTP 请求一同发送到服务器。
可以通过以下方式启用或禁用视图状态:
-
The entire application 通过在 web.config 文件的 <pages> 部分中设置 EnableViewState 属性。
-
A page 通过设置 Page 指令的 EnableViewState 属性,如 <%@ Page Language="C#" EnableViewState="false" %>
-
A control 通过设置 Control.EnableViewState 属性。
它使用由 StateBag 类定义的视图状态对象实现,该类定义了一系列视图状态项。状态包是一种包含属性值对的数据结构,这些对存储为与对象关联的字符串。
StateBag 类具有以下属性:
Properties |
Description |
Item(name) |
具有指定名称的视图状态项的值。这是 StateBag 类的默认属性。 |
Count |
视图状态集合中的项数。 |
Keys |
集合中所有项的键的集合。 |
Values |
集合中所有项的值的集合。 |
StateBag 类具有以下方法:
Methods |
Description |
Add(name, value) |
将项添加到视图状态集合中并更新现有项。 |
Clear |
移除集合中的所有项。 |
Equals(Object) |
确定指定的对象是否等于当前对象。 |
Finalize |
允许它释放资源并执行其他清理操作。 |
GetEnumerator |
返回一个枚举器,用于迭代 StateBag 对象中存储的 StateItem 对象的所有键/值对。 |
GetType |
获取当前实例的类型。 |
IsItemDirty |
检查存储在 StateBag 对象中的 StateItem 对象以评估它是否已修改。 |
Remove(name) |
Removes the specified item. |
SetDirty |
设置 StateBag 对象的状态以及它所包含的每个 StateItem 对象的 Dirty 属性。 |
SetItemDirty |
设置 StateBag 对象中指定 StateItem 对象的 Dirty 属性。 |
ToString |
返回表示状态信息包对象的字符串。 |
Example
以下示例演示了存储视图状态的概念。让我们保留一个计数器,该计数器会在每次通过单击页面上的按钮发回页面时递增。一个标签控件会显示计数器中的值。
标记文件代码如下:
<%@ 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.w3.org/1999/xhtml" >
<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++;
}
}
它将产生以下结果:
Session State
当用户连接到 ASP.NET 网站时,将创建一个新的会话对象。打开会话状态后,将为每次新请求创建新的会话状态对象。此会话状态对象成为上下文的组成部分,并且可通过页面使用。
会话状态通常用于存储应用程序数据,例如库存、供应商列表、客户记录或购物车。它还可以保留有关用户及其偏好的信息,并跟踪正在进行的操作。
会话使用 120 位的 SessionID 进行标识和跟踪,该 SessionID 从客户端传递到服务器,并返回作为 cookie 或修改的 URL。SessionID 是全局唯一且随机的。
会话状态对象从 HttpSessionState 类创建,该类定义了一组会话状态项。
HttpSessionState 类具有以下属性:
Properties |
Description |
SessionID |
The unique session identifier. |
Item(name) |
指定名称所对应的会话状态项的值。这是 HttpSessionState 类的默认属性。 |
Count |
会话状态集合中的项目数量。 |
TimeOut |
获取并设置会话状态提供程序终止会话前允许请求之间经过的时间(分钟)。 |
HttpSessionState 类具有如下的方法:
Methods |
Description |
Add(name, value) |
向会话状态集合中添加一个项目。 |
Clear |
从会话状态集合中删除所有项目。 |
Remove(name) |
从会话状态集合中删除指定的项目。 |
RemoveAll |
从会话状态集合中删除所有键和值。 |
RemoveAt |
从会话状态集合中删除指定索引处的项。 |
会话状态对象是一个键值对,用于存储和检索会话状态对象中的某些信息。您可以针对相同的对象使用如下的代码:
void StoreSessionInfo()
{
String fromuser = TextBox1.Text;
Session["fromuser"] = fromuser;
}
void RetrieveSessionInfo()
{
String fromuser = Session["fromuser"];
Label1.Text = fromuser;
}
上述代码仅在会话字典对象中存储字符串,然而,它可以存储由基本数据类型组成的所有基本数据类型和数组,以及 DataSet、DataTable、HashTable 和 Image 对象,以及继承自 ISerializable 对象的任何用户定义的类。
Example
以下示例展示了存储会话状态的概念。页面上有两个按钮、一个输入字符串的文本框和一个显示上一个会话中存储的文本的标签。
标记文件代码如下:
<%@ 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.w3.org/1999/xhtml" >
<head runat="server">
<title>
Untitled Page
</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table style="width: 568px; height: 103px">
<tr>
<td style="width: 209px">
<asp:Label ID="lblstr" runat="server" Text="Enter a String" style="width:94px">
</asp:Label>
</td>
<td style="width: 317px">
<asp:TextBox ID="txtstr" runat="server" style="width:227px">
</asp:TextBox>
</td>
</tr>
<tr>
<td style="width: 209px"> </td>
<td style="width: 317px"> </td>
</tr>
<tr>
<td style="width: 209px">
<asp:Button ID="btnnrm" runat="server"
Text="No action button" style="width:128px" />
</td>
<td style="width: 317px">
<asp:Button ID="btnstr" runat="server"
OnClick="btnstr_Click" Text="Submit the String" />
</td>
</tr>
<tr>
<td style="width: 209px"> </td>
<td style="width: 317px"> </td>
</tr>
<tr>
<td style="width: 209px">
<asp:Label ID="lblsession" runat="server" style="width:231px" >
</asp:Label>
</td>
<td style="width: 317px"> </td>
</tr>
<tr>
<td style="width: 209px">
<asp:Label ID="lblshstr" runat="server">
</asp:Label>
</td>
<td style="width: 317px"> </td>
</tr>
</table>
</div>
</form>
</body>
</html>
在设计视图中,它应该如下所示:
代码文件如下:
public partial class _Default : System.Web.UI.Page
{
String mystr;
protected void Page_Load(object sender, EventArgs e)
{
this.lblshstr.Text = this.mystr;
this.lblsession.Text = (String)this.Session["str"];
}
protected void btnstr_Click(object sender, EventArgs e)
{
this.mystr = this.txtstr.Text;
this.Session["str"] = this.txtstr.Text;
this.lblshstr.Text = this.mystr;
this.lblsession.Text = (String)this.Session["str"];
}
}
执行该文件并观察其工作方式:
Application State
ASP.NET 应用程序是一个集合,其中包含 Web 服务器上一个虚拟目录中的所有网页、代码和其他文件。如果信息存储在应用程序状态中,所有用户都可以访问。
为了使用应用程序状态,ASP.NET 会针对每个应用程序创建一个应用程序状态对象(来自 HTTPApplicationState 类),并将该对象存储在服务器内存中。此对象由类文件 global.asax 表示。
应用程序状态通常用于存储点击量计数器和其它统计数据、税率、折扣率等全局应用程序数据,以及对访问该网站的用户进行跟踪。
HttpApplicationState 类具有以下属性:
Properties |
Description |
Item(name) |
具有指定名称的应用程序状态项的值。这是 HttpApplicationState 类中的默认属性。 |
Count |
应用程序状态集合中条目的数量。 |
HttpApplicationState 类具有以下方法:
Methods |
Description |
Add(name, value) |
向应用程序状态集合添加一项。 |
Clear |
从应用程序状态集合中删除所有项。 |
Remove(name) |
从应用程序状态集合中删除指定项。 |
RemoveAll |
从 HttpApplicationState 集合中删除所有对象。 |
RemoveAt |
通过索引从集合中删除一个 HttpApplicationState 对象。 |
Lock() |
锁定应用程序状态集合,以便只有当前用户可以访问它。 |
Unlock() |
解锁应用程序状态集合,以便所有用户都可以访问它。 |
通常通过针对以下事件编写处理程序来维护应用程序状态数据:
-
Application_Start
-
Application_End
-
Application_Error
-
Session_Start
-
Session_End
以下代码片段显示了存储应用程序状态信息的基本语法:
Void Application_Start(object sender, EventArgs e)
{
Application["startMessage"] = "The application has started.";
}
Void Application_End(object sender, EventArgs e)
{
Application["endtMessage"] = "The application has ended.";
}