ASP.NET狀態管理

同樣,聽了微軟講師邵志東的講座“ASP.NET狀態管理”的視頻講座,總結如下,希望得到大家的指點:
第一部分:頁面狀態介紹
Http協議————“無狀態協議”
Web服務器每分鐘對上千個用戶進行管理的一種方式就是執行所謂的“無狀態”鏈接。只要有一個希望瀏覽器返回一個頁面、圖像或其他資源的請求,就發生以下事情:
1、連接到服務器
2、告訴服務器想要的頁面、圖像或者其他項
3、服務器發送請求的資源
4、服務器切斷連接,把用戶忘的乾乾淨淨。
也就是頁面之間在Http協議下是沒有任何關係的,這樣就需要有狀態管理來傳輸頁面之間的數據。


WEB頁面處理過程
1、頁面的一次往返處理:用戶對服務器控件的一次操作,就可能引起頁面的一次往返處理:頁面被提交到服務器端,執行響應的事件處理代碼,重建頁面,然後返回到客戶端。
2、頁面重建:每一次頁面被請求,或者頁面事件被提交到服務器,ASP.NET運行環境將執行必要的代碼,重建整個頁面,把結果頁面送到瀏覽器,然後拋棄頁面的變量、控件的狀態和屬性等等頁面信息。
3、頁面處理內部過程:
   (1)、Page_Load:IsPostBack屬性判定頁面是否爲第一次被請求。
   (2)、事件處理:這一階段處理表單的事件
   (3)、Page_Unload:這個階段頁面已經處理完畢,需要做些清理工作,一般地,你可以在這個階段關閉打開文件和數據庫鏈路,或者釋放對象。

ASP.NET Web Form框架的“連續”和“有狀態”假象
訪問者打開頁面的連續畫面,這實際上一種假象,這種假象是由ASP.NET頁框架、頁及其控件實現的。

 

第二部分:基於客戶端的狀態管理:
狀態信息放在客戶端上。
一、視圖狀態(ASP.NET特有)
二、隱藏的窗體域
三、Cookie
四、查詢字符串

一、視圖狀態
ASP.ENT使用了ViewState視圖狀態,是所有服務器控件的一個屬性。如果你查看Web Form產生的HTML代碼,可以看到一個名爲_ViewState的隱藏字段,ASP.NET將狀態信息以Hash的方式存儲在這裏,通過它,可以在下一次回發時知道回發前各控件的狀態。


1<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUILTMyNDAxOTkPZBYCAgQPZBYEAgMPDxYCHgRUZXh0BRvlvZPliY3nlKjmiLfvvJrotoXnuqfnlKjmiLdkZAIHD2QWAmYPDxYGHgtDZWxsUGFkZGluZ2YeC0NlbGxTcGFjaW5nZh4EXyFTQgKAgBhkFiYCAQ9kFgJmD2QWAmYPZBYCZg88KwAJAQAPFgYeDU5ldmVyRXhwYW5kZWRkHgxTZWxlY3RlZE5vZGVkHglMYXN0SW5kZXgCEGRkAgMPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAgUPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCBWRkAgcPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAgkPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCIWRkAgsPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCA2RkAg0PZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCA2RkAg8PZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAhEPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCBGRkAhMPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCCWRkAhUPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAhcPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCBGRkAhkPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAhsPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAh0PZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCA2RkAh8PZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCBmRkAiEPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCCWRkAiMPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCAmRkAiUPZBYCZg9kFgJmD2QWAmYPPCsACQEADxYGHwRkHwVkHwYCA2RkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYTBQ9MZWZ0TWVudTEkY3RsMDAFD0xlZnRNZW51MSRjdGwwMQUPTGVmdE1lbnUxJGN0bDAyBQ9MZWZ0TWVudTEkY3RsMDMFD0xlZnRNZW51MSRjdGwwNAUPTGVmdE1lbnUxJGN0bDA1BQ9MZWZ0TWVudTEkY3RsMDYFD0xlZnRNZW51MSRjdGwwNwUPTGVmdE1lbnUxJGN0bDA4BQ9MZWZ0TWVudTEkY3RsMDkFD0xlZnRNZW51MSRjdGwxMAUPTGVmdE1lbnUxJGN0bDExBQ9MZWZ0TWVudTEkY3RsMTIFD0xlZnRNZW51MSRjdGwxMwUPTGVmdE1lbnUxJGN0bDE0BQ9MZWZ0TWVudTEkY3RsMTUFD0xlZnRNZW51MSRjdGwxNgUPTGVmdE1lbnUxJGN0bDE3BQ9MZWZ0TWVudTEkY3RsMThhvz2XbcWenPMmfNNLRf3pN2JrYw==" />
ASP.NET服務器控件的生命週期:
1、初始化——Init事件(OnInit方法)
2、加載視圖狀態——LoadViewState方法(當頁面回發時,首先從_ViewSatae字段信息中加載該控件的狀態)
3、處理回發數據——LoadPostData方法
4、加載——Load事件(OnLoad方法)
5、發送回發更改通知——RaisePostDataChangedEvent方法
6、處理回發事件——RaisePostBackEvent方法
7、預呈現——PreRender事件(OnPreRender方法)
8、保存視圖狀態——SaveViewState方法
9、呈現——Render方法
10、處置——Dispose方法
11、卸載——UnLoad事件(OnUnLoad方法)


視圖狀態的用法:
1、啓用視圖狀態,即EnableViewState = "true",默認爲true,如果爲false,那麼該控件和子控件的視圖狀態就不會被串行化。
2、可以在視圖狀態中存儲的類型:Int32,bool,string,color,array,arrayList,Unit以及以上類型的HashTable對象
3、視圖狀態與安全
視圖狀態串行化的字符串表達式作爲明文來往返傳送,這是不安全的,在視圖狀態中絕不能保存任何信息(例如口令、連接字符、文件路徑等。)
參考例子(ViewState.aspx和ViewState_userinfo.aspx)


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class ViewState : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Label1.Text = "EnableViewState=True";
                //EnableViewState設爲True時,Lable1的狀態保存在_viewState隱藏字段中,當刷新頁面時,不執行此語句,但是可以從_ViewState中取到以前的狀態信息,所以還是原值。
                Label2.Text = "EnableViewState=False";  
                //EnableViewState設爲False時,Lable2的狀態沒有保存在_viewState隱藏字段中,當刷新頁面時,不執行此語句,並且取不到以前的狀態信息,所以爲空。
            }
        }

        protected void Button2_Click(object sender, EventArgs e)
        {
            if (ViewState["count"] == null)  //從ViewState中讀數據
            { 
                ViewState["count"] = 0;    //向ViewState中保存數據(可以保存多種類型的數據)
            }
            int ncount = (Int32)ViewState["count"];
            ncount += 1;
            ViewState["count"] = ncount;
            Label3.Text = ViewState["count"].ToString();
        }

        protected void Button1_Click(object sender, EventArgs e)
        {

        }
    }
}
二、隱藏的窗體域
1、隱藏域不會顯示在用戶的瀏覽器中,但我們可以像設置標準控制的屬性那樣設置其屬性。當一個網頁被提交給服務器時,隱藏域的內容和其他控制的值一塊兒被送到HTTP Form集合中。隱藏域可以是任何存儲在網頁中的與網頁有關的信息的存儲庫,隱藏域在其value屬性中存儲一個變量,而且必須被顯性地添加在網頁上。
2、ASP.NET中的HtmlInputHidden控制提供了隱藏域的功能。

簡單的說,就是頁面上有一個保存值的隱藏控件,頁面上可以取到它的值,但是看不見它。
例子見(hidden.aspx)

三、Cookie
Cookie定義:
1、由網絡服務器發送出來以儲存在網絡瀏覽器上小量信息;
2、Cookie是把與用戶和網站相關的信息存儲比會話時間還長的一種方式。
3、Cookie存儲在用戶的硬盤上(一般存儲在Web瀏覽器軟件所在的文件夾上,稱爲Cookies)
用途:
1、用戶的個人配置
2、註冊和“Remember me”
3、彈出窗口
如何工作:
1、Cookie存儲在C:/Documents and Settings/<Username>/Cookies下
2、IE選項中的“隱私”選項下修改cookie設置,也可以在“常規”選項卡下選擇“刪除cookie”
如何使用:
1、使用Response對象設置Cookie狀態
   Response.Cookies["UserName"].Value = "張三";
2、使用Request對象讀取已有的Cookie
   string strName = Request.Cookies["UserName"].Value;
3、清除:
   Response.Cookies["UserName"].Value = null;或
   Response.Cookies["UserName"].Expires = new System.DateTime(1999,10,12);(過期)
屬性:
1、Value:值,是string類型的
2、Domain:設置這個屬性後,只有在這個域下才能訪問該Cookie
  例如:
  Response.Cookies["UserName"].Domain = ".Webcast.com.cn";
  //只有指定以“.Webcast.com.cn”結尾的域可以訪問本Cookie
3、Path:該屬性指定那些路徑下的頁面可以訪問此Cookie
4、Expires:指定Cookie過期的日期(清除Cookie)
  Response.Cookies["UserName"].Expires = new System.DateTime(1999,10,12);(過期)

參見實例(Cookie.aspx)
該例子是說在頁面上的TextBox中輸入一個用戶名,然後點“註冊”按鈕,此時將用戶名存入Cookie中,然後在頁面加載時取Cookie值顯示在頁面中,同時10s中自動刪除Cookie。
四、查詢字符串
在講查詢字符串之前先了解一下GET 和 POST方法的不同:
   通過HTTP從Web服務器請求頁面或其他資源,有兩個通用的方法(GET 和 POST方法)。可使用GET方法直接獲得資源,也可使用POST把值傳給相應資源。GET方法是缺省的
   假如把一個或多個成對的名稱/值附在請求頁面的URL後,就變成請求的查詢字符串,且在QueryString集合中提供給ASP頁面。單擊Web頁面、Email消息或其它文檔的超鏈接,或在瀏覽器的地址欄中輸入地址並按回車,或單擊瀏覽器中的Links或Favorites按鈕,所有這些都要使用GET方法。
   因此,對這些動作中傳遞值給ASP的唯一方法是通過QueryString集合,把值附在URL後。
   http://mysite.com/process_page.asp?FirstName=Priscilla&LastName=Descartes
   可以採用如下方式訪問在QueryString集合中提供的值(QueryString就是下面要講的查詢字符串):
   strFirstName = Request.QueryString("FirstName")   ''Return "Priscilla"
   strLastName = Request.QueryString("LastName")     ''Return "Descartes"
   strRaw = Request.QueryString 
   Return "FirstName=Priscilla&LastName=Descartes"
在一個頁面內使用<FORM>段時,可以設置打開的FORM標記的METHOD屬性值爲“GET”或“POST”,缺省值爲“GET”。假如使用“GET”或省略其屬性,瀏覽器將該值綁定在頁面所有控件上,成爲一個查詢字符串,且附在被請求頁面的URL上。當這個請求到達Web服務器時,其值由ASP的Request.QueryString集合提供。然而,假如設置METHOD屬性爲“POST”,瀏覽器將值包裝進發送服務器的HTTP報頭中,通過Request.Form集合提供給ASP。
   通常來說,可以在所有的HTML窗體中使用GET方法。然而,瀏覽器或服務器的URL字符串長度存在一定的限制。因此,附有長的字符串可能會引起溢出和某些字符串的字符被截掉。同時,查詢字符串出現在瀏覽器的地址欄和所有的保存的鏈接和收藏夾中。不僅如此,還顯露了通過Web服務器時在HTTP請求中不想顯示的值,它也可能出現你的服務器和其他路由服務器的日誌文件中。在HTTP請求報頭中的值很少是可見的,並且不出現在日誌文件中。
   使用POST方法需要注意的小問題是,當用戶重新下載<FORM>時,窗體的值將不再保留,其值爲空且必須重新輸入。然而,當附在URL上時,其值被存儲爲一個鏈接,將被保留,因此將出現在所有的URL與字符串結合的請求中,這或許是個優點也可能是個缺點,這根據應用而定(一些瀏覽器在客戶端上能夠在一定範圍內自動保留一個頁面上的值)。

先看看get方法(利用查詢字符串):
1、查詢字符串提供了一種簡單而受限制的維護狀態信息的方法,我們可以方便地給那個信息從一個網頁傳遞給另一個網頁。
2、帶有查詢字符串的URL如下所示:
http://localhost:1305/QueryString_Show.aspx?username=xieex&password=1111
3、使用:
string sUserName,sPwd;
sUserName = Request.Params["username"].ToString();
sPwd = Request.Params["password"].ToString();

sUserName = Request.QueryString["username"].ToString();
sPwd = Request.QueryString["password"].ToString();

sUserName = Request["username"].ToString();
sPwd = Request["password"].ToString();
都可以取到xieex和1111

其實這樣的傳值方式很常見也很有用,例如有些系統中,Gird中有很多條數據,我可以對某條數據進行瀏覽或者編輯,當點“瀏覽”按鈕時,我彈出對話框對該條記錄進行瀏覽,此時不允許編輯,此時我就需要從主頁面上傳一個狀態(state)到對話框頁面上來,然後在對話框頁面上取其狀態(Request["state"].ToString()),此時根據其值(edit或browse)就可以控制是否可以編輯了。

參見實例(QueryString.aspx和QueryString_Show.aspx)
該例子是說在QueryString.aspx頁面上註冊用戶名和密碼,然後跳轉到另一個頁面上,在另一個頁面上取其用戶名和密碼。
在該頁面上註冊用戶名和密碼


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class Cookie : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.Cookies["UserName"] != null)  //注意是Request
            {
                Response.Write("親愛的" + Request.Cookies["UserName"].Value + ",歡迎你光臨!");
               
            }
            else
            {
                Response.Write("歡迎光臨!");
            }
           
        }

        protected void btnZC_Click(object sender, EventArgs e)
        {
            Response.Cookies["UserName"].Value = txtUser.Text;
            Response.Cookies["UserName"].Expires = DateTime.Now.AddSeconds(10);  //10秒鐘後失效,即Cookies["UserName"]的信息丟失;或者手工刪除(IE中選項刪除Cookie)
        }
    }
}using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class QueryString : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            Response.Redirect("QueryString_Show.aspx?username=" + txtUser.Text + "&password=" + txtPwd.Text);
        }
    }
}
在另一個頁面上取用戶名和密碼:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class QueryString_Show : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write("用戶:" + Request.Params["username"]+"<br>");
            Response.Write("密碼:" + Request.Params["password"]+"<br>");

            Response.Write("用戶:" + Request.QueryString["username"]+"<br>");//get方法時用Request.QueryString
            Response.Write("密碼:" + Request.QueryString["password"]+"<br>");

            Response.Write("用戶:" + Request["username"]+"<br>");
            Response.Write("密碼:" + Request["password"]+"<br>");
        }
    }
}
再看看post方法

直接看例子:(Post.aspx和post_acc.aspx)
該例子和上面例子差不多,是說在Post.aspx頁面上註冊用戶名和密碼,然後跳轉到另一個頁面上,在另一個頁面上取其用戶名和密碼。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Post.aspx.cs" Inherits="ASPNETState.Post" %>

<!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>無標題頁</title>
</head>
<body>
     <!--注意action="post_acc.aspx" method="post"-->
    <form action="post_acc.aspx" method="post">
    <div>
        用戶:<input id="txtUser" type="text" name="username" /><br />
        <br />
        密碼:<input id="txtPwd" type="text" name="pwd" /><br />
        <br />
        <input id="Button1" type="submit" value="提交"  /></div>
        <!--注意按鈕的type爲submit-->
    </form>
</body>
</html>
在另一個頁面上取用戶名和密碼:


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class post_acc : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Response.Write(Server.MapPath("post.aspx"));

                Response.Write("用戶:" + Request.Form["username"]);//post方法時用Request.Form
                Response.Write("密碼:"  + Request.Params["pwd"]);
            }
        }
    }
}
第三部分 基於服務器的狀態管理
信息存儲在服務器上,儘管其安全型較高,但會佔用較多的web服務器資源。服務器端通常用以下方式實現狀態管理:
一、Application對象
二、Session對象

 

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class ApplicationState : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Application.Lock();  //加鎖,防止併發,保證同一時間只有一個用戶對其訪問
            if (Application["count"] != null)
            {
                Application["count"] = (Int32)Application["count"] + 1;
            }
            else
            {
                Application["count"] = 1;
            }
            Application.UnLock();
            Response.Write("您是第"+Application["count"]+"位訪問者!"); 
           //每訪問一次都加1,只有當IIS服務重啓時纔會清零

        }
    }
}
另一個例子(模擬網站的當前用戶人數和訪問總人數)
Global.asax


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.IO;

namespace ASPNETState
{
    public class Global : System.Web.HttpApplication
    {
        /**//// <summary>
        /// 必需的設計器變量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        private FileStream fileStream;
        private StreamReader reader;//讀字符流
        private StreamWriter writer;//寫字符流

        public Global()
        {
            InitializeComponent();
        }   

        protected void Application_Start(object sender, EventArgs e)
        {
            Application["CurrentGuests"] = 0;//初始花爲0;
            fileStream = File.Open(Server.MapPath("counts.text"), FileMode.OpenOrCreate);//文件不存在,創建文件
            reader = new StreamReader(fileStream);//要讀取的完整路徑
            Application["AllGuests"] = Convert.ToInt32(reader.ReadLine()); //從當前流中讀取一行字符並將數據作爲字符串返回
            reader.Close();//關閉流
        }

        protected void Session_Start(Object sender, EventArgs e)//當用戶訪問網站時,在線用戶+1,總訪問數+1
        {
            Application.Lock();//同步,避免同時寫入

            Application["CurrentGuests"] = (int)Application["CurrentGuests"] + 1;//總在線用戶數
            Application["AllGuests"] = (int)Application["AllGuests"] + 1;//訪問網站的總用戶數
            fileStream = new FileStream(Server.MapPath("counts.text"), FileMode.OpenOrCreate, FileAccess.ReadWrite);//
            writer = new StreamWriter(fileStream);//實現一個寫入流,使其以一種特定的編碼向流中寫入字符
            writer.WriteLine(Application["AllGuests"].ToString());//把訪問網站的總用戶數再次寫入到文件
            writer.Close();//關閉寫入流

            Application.UnLock();//同步結束
        }

        protected void Application_BeginRequest(Object sender, EventArgs e)
        {

        }

        protected void Application_EndRequest(Object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        {

        }

        protected void Application_Error(Object sender, EventArgs e)
        {

        }

        protected void Session_End(Object sender, EventArgs e)//當前用戶退出網站時,在線用戶數量-1,
        {
            Application.Lock();
            Application["CurrentGuests"] = (int)Application["CurrentGuests"] - 1;//總在線用戶數量-1
            Application.UnLock();

        }

        protected void Application_End(Object sender, EventArgs e)
        {

        }
           

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
        }
    }
}
在頁面上顯示,需寫代碼:


        protected void Page_Load(object sender, EventArgs e)
        {
            this.Label1.Text = "正在訪問站點的用戶數:" + Application["CurrentGuests"].ToString();
            this.Label2.Text = "訪問過站點的總用戶數:" + Application["AllGuests"].ToString();
        }
Application對象的使用建議:
1、對於頻繁使用(很多用戶都要使用的)的數據使用該對象
2、不要把太多的信息放在該對象中
3、如果站點有很大的通信量,建議使用Web.Config


二、Session狀態
對網站的一次訪問叫做會話(Session),超時後,自動結束會話(一般是20分鐘),Session也是保存在服務器內存中的。
使用Session時的情況,如:
1、購物車:網絡用戶決定購買的商品列表
2、用戶信息:訪問者的姓名
3、用戶設置:個性化界面
等等

ASP.NET會話狀態模塊在Web.config文件中像這樣配置(不進行額外設置,以下是默認設置)的:
<sessionState mode="InProc" cookieless="false" timeout="20" />
mode屬性設爲InProc(默認值),表明會話狀態要由ASP.NET存儲在內存中
cookieless屬性設爲false,表明不用Cookie來傳遞會話ID,這就避免了用戶禁用了Cookie,Session對象無數據可用。
timeout屬性設爲20,表示登錄網站後,如果20分鐘不對其進行操作,則該會話結束,需要重新登錄。

Session屬性和方法:
1、TimeOut屬性:
獲取和設置會話結束之前的時間段,以分鐘爲單位,默認爲20分鐘
2、Abandon():
結束當前會話,會話中的所有信息都被清空
3、Clear():
刪除當前會話中的所有信息,但不結束會話
4、IsNewSession:
如果會話是在用戶訪問頁面時創建的,則這個屬性返回true,當會話需要對某些數據進行初始化後才能使用時,就可以使用這個屬性


參見實例(SessionState.aspx和SessionState_Redirect.aspx)
該例子是說在SessionState.aspx頁面上註冊用戶名和密碼,然後跳轉到另一個頁面上,在另一個頁面上取其用戶名和密碼。
在該頁面上註冊用戶名和密碼


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class SessionState : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            Session["user"] = txtUser.Text;
            Session["pwd"] = txtPwd.Text;
            Response.Redirect("SessionState_Redirect.aspx");
        }
    }
}
在另一個頁面上取用戶名和密碼:


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace ASPNETState
{
    public partial class SessionState_Redirect : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Label1.Text = Session["user"].ToString();
            Label2.Text = Session["pwd"].ToString();
        }
    }
}
Application和Session狀態的區別:
簡單的說,Application是應用程序級別的狀態存儲,Session是會話級別的狀態存儲。
另外作用域不同,
Application對象針對所有用戶都生效
Session對象則相反,每個用戶都有自己的Session對象,它的生命週期起始於服務器產生對用戶請求頁面的響應,終止於用戶斷開與服務器的連接。
舉例來說,當手機開機時,相當於一個Applicaion開始,然後當一個朋友打電話過來,此時一個Session開始,掛電話時相當於這個Session結束,然後又有一個朋友打電話過來,此時另一個Session開始。手機未關機說明Application還未結束


由於Application和Session狀態都存儲在內存中,但是當服務器重新啓動時,保留的狀態就會消失了,爲了保留其狀態,就必須將狀態保存到數據庫。如網站計數器

最後對各個狀態進行總結:
爲了更清楚的瞭解,我們總結出每一種對象應用的具體環境,如下表所示:


1、ViewState對象
    ViewState 常用於保存單個用戶的狀態信息,有效期等於頁面的生存期。ViewState容器可以保持大量的數據,但是必須謹慎使用,因爲過多使用會影響應用程序的性能。所有Web服務器控件都使用ViewState在頁面回發期音保存自己的狀態信息。如果某個控件不需要在回發期間保存狀態信息,最好關閉該對象的ViewState,避免不必要的資源浪費。通過給@Page指令添加“EnableViewState=false”屬性可以禁止整個頁面的ViewState。

2、隱藏域
  Hidden控件是屬於HTML類型的服務器控件,使用此控件可以實現隱藏域的功能。其實此控件和其它服務器控件的使用沒有太大區別,只是它不會在用戶端的瀏覽器中顯示,始終處於隱藏狀態。但是每次頁面提交的時候,此控件和其它服務器控件一同提交到服務器端,因此在服務器端可以使用Value屬性獲取或保存一些數據信息。

3、Cookie對象
    Cookie用於保存客戶瀏覽器請求服務器頁面的請求信息,程序員也可以用它存放非敏感性的用戶信息,信息保存的時間可以根據需要設置.如果沒有設置Cookie失效日期,它們僅保存到關閉瀏覽器程序爲止.如果將Cookie對象的Expires屬性設置爲Minvalue,則表示Cookie永遠不會過期.Cookie存儲的數據量很受限制,大多數瀏覽器支持最大容量爲4096,因此不要用來保存數據集及其他大量數據.由於並非所有的瀏覽器都支持Cookie,並且數據信息是以明文文本的形式保存在客戶端的計算機中,因此最好不要保存敏感的,未加密的數據,否則會影響網站的安全性。


4、查詢字符串
  查詢字符串的方式是將要傳遞的值連接在URL後面,然後通過Response.Redirect方法實現客戶端的重定向。這種方式可以實現在兩個頁面之間傳遞信息。由於URL的長度有一定的限制,因此不能傳遞太大的信息,加外安全性也不是很好。


5、Application對象
    Application用於保存所有用戶的公共的數據信息,如果使用Application對象,一個需要考慮的問題是任何寫操作都要在Application_OnStart事件(global.asax)中完成.儘管使用Application.Lock和Applicaiton.Unlock方法來避免寫操作的同步,但是它串行化了對Application對象的請求,當網站訪問量大的時候會產生嚴重的性能瓶頸.因此最好不要用此對象保存大的數據集合。

6、Session對象
    Session用於保存每個用戶的專用信息.她的生存期是用戶持續請求時間再加上一段時間(一般是20分鐘左右).Session中的信息保存在Web服務器內容中,保存的數據量可大可小.當Session超時或被關閉時將自動釋放保存的數據信息.由於用戶停止使用應用程序後它仍然在內存中保持一段時間,因此使用Session對象使保存用戶數據的方法效率很低.對於小量的數據,使用Session對象保存還是一個不錯的選擇。

7、Cache對象
   Cache對象用於在HTTP請求間保存頁面或數據。該對象的使用可以極大地提高整個應用程序的效率。它允許將頻繁訪問的大量服務器資源存儲在內存中,當用戶發出相同的請求後服務器不再次處理而是將Cache中保存的信息返回給用戶,節省了服務器處理請求的時間。此對象的實例是每個應用程序專用的,其生存期依賴於該應用程序的生存期。當重新啓動應用程序時,將重新創建其Cache對象的實例。使用Cache對象保存信息的代碼如下。   //存放信息
  Cache["nameID"]="0001";
  //存放信息
  Cache.Insert("nameID","0001"1);
  //讀取信息
  string NameID=Cache["nameID"].ToString();

具體例子代碼見附件:
ASPNETState.rar


一、Application狀態
1、應用程序級別的狀態存取(就是說服務器上的應用程序,各個客戶端都可以訪問它)
2、變量狀態的存儲和提取
   存儲: Application["username"] = "xieex";
   提取: string strUserName = Application["username"];
3、同時訪問要加鎖,防止併發衝突
   Application.Lock();
   Application.Unlock();
Application是保存在服務器內存中的。
參見實例(ApplicationState.aspx)
該實例用於記錄訪問該頁面的訪問者個數,用Application存儲變量,這樣不會因爲一次會話結束而把訪問記錄清零。
   方法
 信息量大小
 保存時間
 應用範圍
 保存位置
 
Application
 任意大小
 整個應用程序的生命期
 所有用戶
 服務器端
 
Session
 小量,簡單的數據
 用戶活動時間+一段延遲時間(一般
爲20分鐘)
 單個用戶
 服務器端
 
Cookie
 小量,簡單的數據
 可以根據需要設定
 單個用戶
 客戶端
 
Viewstate
 小量,簡單的數據
 一個Web頁面的生命期
 單個用戶
 客戶端
 
Cache
 任意大小
 可以根據需要設定
 所有用戶
 服務器端
 
隱藏域
 小量,簡單的數據
 一個Web頁面的生命期
 單個用戶
 客戶端
 
查詢字符串
 小量,簡單的數據
 直到下次頁面跳轉請求
 單個用戶
 客戶端
 
Web.Config文件
 不變或極少改變的小量數據
 直到配置文件被更新
 單個用戶
 服務器端
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章