超文本傳輸協(xié)議(HTTP)是一種無狀態(tài)協(xié)議。 當(dāng)客戶端從服務(wù)器斷開連接時(shí),ASP.NET引擎將丟棄頁面對象。 這樣,每個(gè)Web應(yīng)用程序都可以擴(kuò)展以同時(shí)提供大量請求,而不會耗盡服務(wù)器內(nèi)存。
但是,需要一些技術(shù)來在請求之間存儲信息并在需要時(shí)檢索相關(guān)信息。即當(dāng)前會話中當(dāng)前用戶的所有控制和變量的當(dāng)前值被稱為狀態(tài)。
ASP.NET管理四種類型的狀態(tài):
視圖狀態(tài)是頁面及其所有控件的狀態(tài)。 它由ASP.NET框架在發(fā)送之間自動維護(hù)。
當(dāng)頁面被發(fā)送回客戶端時(shí),頁面及其控件屬性的改變被確定,并存儲在名為_VIEWSTATE的隱藏輸入字段的值中。當(dāng)頁面再次被回發(fā)時(shí),_VIEWSTATE字段被發(fā)送到具有HTTP請求的服務(wù)器。
視圖狀態(tài)可以被啟用或禁用:
Web.config文件的<pages>部分中設(shè)置EnableViewState屬性。Page指令的EnableViewState屬性設(shè)置為<%@ Page Language="C#" EnableViewState="false" %>Control.EnableViewState屬性。它使用由StateBag類定義的視圖狀態(tài)對象來實(shí)現(xiàn),該類定義視圖狀態(tài)項(xiàng)的集合。狀態(tài)包是一個(gè)包含屬性值對的數(shù)據(jù)結(jié)構(gòu),存儲為與對象關(guān)聯(lián)的字符串。
StateBag類具有以下屬性:
| 編號 | 屬性 | 描述 |
|---|---|---|
| 1 | Item(name) |
具有指定名稱的視圖狀態(tài)項(xiàng)目的值。這是StateBag類的默認(rèn)屬性。 |
| 2 | Count |
視圖狀態(tài)集合中的項(xiàng)目數(shù)量。 |
| 3 | Keys |
集合中所有項(xiàng)目的鍵集合。 |
| 4 | Values |
集合中所有項(xiàng)目的值的集合。 |
StateBag類具有以下方法:
| 編號 | 方法 | 描述 |
|---|---|---|
| 1 | Add(name, value) |
將項(xiàng)目添加到視圖狀態(tài)集合,并更新現(xiàn)有項(xiàng)目。 |
| 2 | Clear |
刪除集合中的所有項(xiàng)目。 |
| 3 | Equals(Object) |
確定指定的對象(Object)是否等于當(dāng)前對象。 |
| 4 | Finalize |
允許它釋放資源并執(zhí)行其他清理操作。 |
| 5 | GetEnumerator |
返回一個(gè)枚舉器,該枚舉器遍歷存儲在StateBag對象中的StateItem對象的所有鍵/值對。 |
| 6 | GetType |
獲取當(dāng)前實(shí)例的類型。 |
| 7 | IsItemDirty |
檢查存儲在StateBag對象中的StateItem對象,以確定它是否已被修改。 |
| 8 | Remove(name) |
刪除指定的項(xiàng)目。 |
| 9 | SetDirty |
設(shè)置StateBag對象的狀態(tài)以及它包含的每個(gè)StateItem對象的Dirty屬性。 |
| 10 | SetItemDirty |
設(shè)置StateBag對象中指定的StateItem對象的Dirty屬性。 |
| 11 | ToString |
返回表示狀態(tài)包對象的字符串。 |
以下示例演示了存儲視圖狀態(tài)的概念。使用一個(gè)計(jì)數(shù)器,通過單擊頁面上的按鈕,每次頁面被重新發(fā)送時(shí),計(jì)數(shù)器都會增加。 另一個(gè)標(biāo)簽控件顯示計(jì)數(shù)器中的值。
首先啟動Visual Studio,創(chuàng)建一個(gè)名稱為:ManagingState 的空網(wǎng)站項(xiàng)目,如下所示 -

添加一個(gè)新的窗體頁面 - ViewState.aspx,如下所示 -

ViewState.aspx 的代碼實(shí)現(xiàn)如下 -
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ViewState.aspx.cs" Inherits="ViewState" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>視圖狀態(tài)</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h3>視圖狀態(tài)示例</h3>
頁面計(jì)數(shù)器:
<asp:Label ID="lblCounter" runat="server" />
<asp:Button ID="btnIncrement" runat="server" Text="添加計(jì)數(shù)" onclick="btnIncrement_Click" />
</div>
</form>
</body>
</html>
后端實(shí)現(xiàn)的Default.aspx.cs 如下 -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class ViewState : 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)
{
counter = counter + 1;
lblCounter.Text = counter.ToString();
}
protected void btnIncrement_Click(object sender, EventArgs e)
{
//counter = counter + 1;
lblCounter.Text = counter.ToString();
}
}
運(yùn)行后,得到以下結(jié)果 -

控件狀態(tài)不能修改,直接訪問或禁用。
當(dāng)用戶連接到ASP.NET網(wǎng)站時(shí),會創(chuàng)建一個(gè)新的會話對象。 當(dāng)會話狀態(tài)打開時(shí),會為每個(gè)新請求創(chuàng)建一個(gè)新的會話狀態(tài)對象。 此會話狀態(tài)對象成為上下文的一部分,并通過該頁面可用。
會話狀態(tài)通常用于存儲應(yīng)用程序數(shù)據(jù),如庫存,供應(yīng)商列表,客戶記錄或購物車。 它還可以保存關(guān)于用戶和他的偏好的信息,并保持未決操作的軌跡。
會話使用120位長度的SessionID進(jìn)行標(biāo)識和跟蹤,SessionID從客戶端傳遞到服務(wù)器,并作為cookie或修改后的URL返回。 SessionID是全局唯一和隨機(jī)的。
會話狀態(tài)對象是從HttpSessionState類創(chuàng)建的,該類定義了會話狀態(tài)項(xiàng)的集合。
HttpSessionState類具有以下屬性:
| 編號 | 屬性 | 描述 |
|---|---|---|
| 1 | SessionID |
唯一的會話標(biāo)識符。 |
| 2 | Item(name) |
具有指定名稱的會話狀態(tài)項(xiàng)的值。這是HttpSessionState類的默認(rèn)屬性。 |
| 3 | Count |
會話狀態(tài)集合中的項(xiàng)目數(shù)量。 |
| 4 | TimeOut |
獲取并設(shè)置會話狀態(tài)提供程序終止會話之前請求之間允許的時(shí)間量(以分鐘為單位)。 |
HttpSessionState類具有以下方法:
| 編號 | 方法 | 描述 |
|---|---|---|
| 1 | Add(name, value) |
將項(xiàng)目添加到會話狀態(tài)集合。 |
| 2 | Clear |
從會話狀態(tài)集合中刪除所有項(xiàng)目。 |
| 3 | Remove(name) |
從會話狀態(tài)集合中刪除指定的項(xiàng)目。 |
| 4 | RemoveAll |
從會話狀態(tài)集合中刪除所有的鍵和值。 |
| 5 | RemoveAt |
從會話狀態(tài)集合中刪除指定索引處的項(xiàng)目。 |
會話狀態(tài)對象是一個(gè)名稱-值對,用于存儲和檢索會話狀態(tài)對象的一些信息??梢允褂孟旅娴拇a來做同樣的事情:
void StoreSessionInfo()
{
String fromuser = TextBox1.Text;
Session["fromuser"] = fromuser;
}
void RetrieveSessionInfo()
{
String fromuser = Session["fromuser"];
Label1.Text = fromuser;
}
上面的代碼只存儲Session字典對象中的字符串,但是它可以存儲所有由基本數(shù)據(jù)類型組成的基本數(shù)據(jù)類型和數(shù)組,以及DataSet,DataTable,HashTable和Image對象, 定義的類從ISerializable對象繼承。
示例
以下示例演示了存儲會話狀態(tài)的概念。 在頁面上有兩個(gè)按鈕,一個(gè)輸入字符串的文本框和一個(gè)標(biāo)簽來顯示上次會話存儲的文本。
在項(xiàng)目:ManagingState 上創(chuàng)建一個(gè)新的窗體文件:SessionState.aspx ,如下所示 -

參考以下代碼(SessionState.aspx) -
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SessionState.aspx.cs" Inherits="SessionState" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Session狀態(tài)</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="輸入一個(gè)字符串:" 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="無動作按鈕" style="width:128px" />
</td>
<td style="width: 317px">
<asp:Button ID="btnstr" runat="server"
OnClick="btnstr_Click" Text="提交" />
</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>
在設(shè)計(jì)視圖中應(yīng)該如下所示:

文件后端處理的代碼(SessionState.aspx.cs)如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class SessionState : 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"];
}
}
執(zhí)行該文件并觀察其結(jié)果和工作原理:

ASP.NET應(yīng)用程序是Web服務(wù)器上單個(gè)虛擬目錄中的所有網(wǎng)頁,代碼和其他文件的集合。 信息以應(yīng)用程序狀態(tài)存儲時(shí),所有用戶都可以使用。
為了提供應(yīng)用程序狀態(tài)的使用,ASP.NET從HTTPApplicationState類為每個(gè)應(yīng)用程序創(chuàng)建一個(gè)應(yīng)用程序狀態(tài)對象,并將此對象存儲在服務(wù)器內(nèi)存中。該對象由類文件global.asax表示。
應(yīng)用程序狀態(tài)主要用于存儲點(diǎn)擊計(jì)數(shù)器和其他統(tǒng)計(jì)數(shù)據(jù),全局應(yīng)用程序數(shù)據(jù)(如稅率,折扣率等),并保持用戶訪問該網(wǎng)站的軌跡。
HttpApplicationState類具有以下屬性:
| 編號 | 屬性 | 描述 |
|---|---|---|
| 1 | Item(name) |
具有指定名稱的應(yīng)用程序狀態(tài)項(xiàng)的值。 這是HttpApplicationState類的默認(rèn)屬性。 |
| 2 | Count |
應(yīng)用程序狀態(tài)集合中的項(xiàng)目數(shù)。 |
HttpApplicationState類具有以下方法:
| 編號 | 方法 | 描述 |
|---|---|---|
| 1 | Add(name, value) |
將項(xiàng)目添加到應(yīng)用程序狀態(tài)集合。 |
| 2 | Clear |
從應(yīng)用程序狀態(tài)集合中刪除所有項(xiàng)目。 |
| 3 | Remove(name) |
從應(yīng)用程序狀態(tài)集合中刪除指定的項(xiàng)目。 |
| 4 | RemoveAll |
從HttpApplicationState集合中刪除所有對象。 |
| 5 | RemoveAt |
通過索引從集合中刪除HttpApplicationState對象。 |
| 6 | Lock() |
鎖定應(yīng)用程序狀態(tài)集合,以便只有當(dāng)前用戶可以訪問它。 |
| 7 | Unlock() |
解鎖應(yīng)用程序狀態(tài)收集,以便所有用戶都可以訪問它。 |
應(yīng)用程序狀態(tài)數(shù)據(jù)通常通過為事件編寫處理程序來維護(hù):
以下代碼片段顯示了存儲應(yīng)用程序狀態(tài)信息的基本語法:
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.";
}