ASP.NET管理狀態


超文字傳輸協定(HTTP)是一種無狀態協定。 當用戶端從伺服器斷開連線時,ASP.NET引擎將丟棄頁面物件。 這樣,每個Web應用程式都可以擴充套件以同時提供大量請求,而不會耗盡伺服器記憶體。

但是,需要一些技術來在請求之間儲存資訊並在需要時檢索相關資訊。即當前對談中當前使用者的所有控制和變數的當前值被稱為狀態。

ASP.NET管理四種型別的狀態:

  • 檢視狀態
  • 控制元件狀態
  • 對談狀態
  • 應用狀態

檢視狀態

檢視狀態是頁面及其所有控制元件的狀態。 它由ASP.NET框架在傳送之間自動維護。

當頁面被傳送回用戶端時,頁面及其控制元件屬性的改變被確定,並儲存在名為_VIEWSTATE的隱藏輸入欄位的值中。當頁面再次被回發時,_VIEWSTATE欄位被傳送到具有HTTP請求的伺服器。

檢視狀態可以被啟用或禁用:

  • 整個應用程式通過在Web.config檔案的<pages>部分中設定EnableViewState屬性。
  • 通過將Page指令的EnableViewState屬性設定為<%@ Page Language="C#" EnableViewState="false" %>
  • 通過設定控制元件的Control.EnableViewState屬性。

它使用由StateBag類定義的檢視狀態物件來實現,該類定義檢視狀態項的集合。狀態包是一個包含屬性值對的資料結構,儲存為與物件關聯的字串。

StateBag類具有以下屬性:

編號 屬性 描述
1 Item(name) 具有指定名稱的檢視狀態專案的值。這是StateBag類的預設屬性。
2 Count 檢視狀態集合中的專案數量。
3 Keys 集合中所有專案的鍵集合。
4 Values 集合中所有專案的值的集合。

StateBag類具有以下方法:

編號 方法 描述
1 Add(name, value) 將專案新增到檢視狀態集合,並更新現有專案。
2 Clear 刪除集合中的所有專案。
3 Equals(Object) 確定指定的物件(Object)是否等於當前物件。
4 Finalize 允許它釋放資源並執行其他清理操作。
5 GetEnumerator 返回一個列舉器,該列舉器遍歷儲存在StateBag物件中的StateItem物件的所有鍵/值對。
6 GetType 獲取當前範例的型別。
7 IsItemDirty 檢查儲存在StateBag物件中的StateItem物件,以確定它是否已被修改。
8 Remove(name) 刪除指定的專案。
9 SetDirty 設定StateBag物件的狀態以及它包含的每個StateItem物件的Dirty屬性。
10 SetItemDirty 設定StateBag物件中指定的StateItem物件的Dirty屬性。
11 ToString 返回表示狀態包物件的字串。

範例

以下範例演示了儲存檢視狀態的概念。使用一個計數器,通過單擊頁面上的按鈕,每次頁面被重新傳送時,計數器都會增加。 另一個標籤控制元件顯示計數器中的值。

首先啟動Visual Studio,建立一個名稱為:ManagingState 的空網站專案,如下所示 -

新增一個新的表單頁面 - ViewState.aspx,如下所示 -

ViewState.aspx 的程式碼實現如下 -

<%@ 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>檢視狀態</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <h3>檢視狀態範例</h3>

            頁面計數器:

            <asp:Label ID="lblCounter" runat="server" />
            <asp:Button ID="btnIncrement" runat="server" Text="新增計數" onclick="btnIncrement_Click" />
         </div>
    </form>
</body>
</html>

後端實現的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();
    }
}

執行後,得到以下結果 -

控制元件狀態

控制元件狀態不能修改,直接存取或禁用。

對談狀態

當使用者連線到ASP.NET網站時,會建立一個新的對談物件。 當對談狀態開啟時,會為每個新請求建立一個新的對談狀態物件。 此對談狀態物件成為上下文的一部分,並通過該頁面可用。

對談狀態通常用於儲存應用程式資料,如庫存,供應商列表,客戶記錄或購物車。 它還可以儲存關於使用者和他的偏好的資訊,並保持未決操作的軌跡。

對談使用120位長度的SessionID進行標識和跟蹤,SessionID從用戶端傳遞到伺服器,並作為cookie或修改後的URL返回。 SessionID是全域性唯一和隨機的。

對談狀態物件是從HttpSessionState類建立的,該類定義了對談狀態項的集合。

HttpSessionState類具有以下屬性:

編號 屬性 描述
1 SessionID 唯一的對談識別符號。
2 Item(name) 具有指定名稱的對談狀態項的值。這是HttpSessionState類的預設屬性。
3 Count 對談狀態集合中的專案數量。
4 TimeOut 獲取並設定對談狀態提供程式終止對談之前請求之間允許的時間量(以分鐘為單位)。

HttpSessionState類具有以下方法:

編號 方法 描述
1 Add(name, value) 將專案新增到對談狀態集合。
2 Clear 從對談狀態集合中刪除所有專案。
3 Remove(name) 從對談狀態集合中刪除指定的專案。
4 RemoveAll 從對談狀態集合中刪除所有的鍵和值。
5 RemoveAt 從對談狀態集合中刪除指定索引處的專案。

對談狀態物件是一個名稱-值對,用於儲存和檢索對談狀態物件的一些資訊。可以使用下面的程式碼來做同樣的事情:

void StoreSessionInfo()
{
   String fromuser = TextBox1.Text;
   Session["fromuser"] = fromuser;
}

void RetrieveSessionInfo()
{
   String fromuser = Session["fromuser"];
   Label1.Text = fromuser;
}

上面的程式碼只儲存Session字典物件中的字串,但是它可以儲存所有由基本資料型別組成的基本資料型別和陣列,以及DataSetDataTableHashTableImage物件, 定義的類從ISerializable物件繼承。

範例

以下範例演示了儲存對談狀態的概念。 在頁面上有兩個按鈕,一個輸入字串的文字框和一個標籤來顯示上次對談儲存的文字。

在專案:ManagingState 上建立一個新的表單檔案: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狀態</title>
</head>
<body>
    <form id="form1" runat="server">
         <div>
            &nbsp; &nbsp; &nbsp;

            <table style="width: 568px; height: 103px">

               <tr>
                  <td style="width: 209px">
                     <asp:Label ID="lblstr" runat="server" Text="輸入一個字串:"  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>

在設計檢視中應該如下所示:

檔案後端處理的程式碼(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"];
    }
}

執行該檔案並觀察其結果和工作原理:

 Application狀態

ASP.NET應用程式是Web伺服器上單個虛擬目錄中的所有網頁,程式碼和其他檔案的集合。 資訊以應用程式狀態儲存時,所有使用者都可以使用。

為了提供應用程式狀態的使用,ASP.NET從HTTPApplicationState類為每個應用程式建立一個應用程式狀態物件,並將此物件儲存在伺服器記憶體中。該物件由類檔案global.asax表示。

應用程式狀態主要用於儲存點選計數器和其他統計資料,全域性應用程式資料(如稅率,折扣率等),並保持使用者存取該網站的軌跡。

HttpApplicationState類具有以下屬性:

編號 屬性 描述
1 Item(name) 具有指定名稱的應用程式狀態項的值。 這是HttpApplicationState類的預設屬性。
2 Count 應用程式狀態集合中的專案數。

HttpApplicationState類具有以下方法:

編號 方法 描述
1 Add(name, value) 將專案新增到應用程式狀態集合。
2 Clear 從應用程式狀態集合中刪除所有專案。
3 Remove(name) 從應用程式狀態集合中刪除指定的專案。
4 RemoveAll HttpApplicationState集合中刪除所有物件。
5 RemoveAt 通過索引從集合中刪除HttpApplicationState物件。
6 Lock() 鎖定應用程式狀態集合,以便只有當前使用者可以存取它。
7 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.";
}