ASP.NET狀態管理 (2)

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)
   }
   }
  }
  四、查詢字符串
  在講查詢字符串之前先了解一下GET 和 POST方法的不同:
   通過HTTP從Web服務器請求頁面或其他資源,有兩個通用的方法(GET 和 POST方法)。可使用GET方法直接獲得資源,也可使用POST把值傳給相應資源。GET方法是缺省的
   假如把一個或多個成對的名稱/值附在請求頁面的URL後,就變成請求的查詢字符串,且在QueryString集合中提供給ASP頁面。單擊Web頁面、Email消息或其它文檔的超鏈接,或在瀏覽器的地址欄中輸入地址並按回車,或單擊瀏覽器中的Links或Favorites按鈕,所有這些都要使用GET方法。
   因此,對這些動作中傳遞值給ASP的唯一方法是通過QueryString集合,把值附在URL後。
   [url]http://mysite.com/process_page.asp?FirstName=Priscilla&LastName=Descartes[/url]
   可以採用如下方式訪問在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如下所示:
  [url]http://localhost:1305/QueryString_Show.aspx?username=xieex&password=1111[/url]
  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 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" "[url]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd[/url]">
  
  <html xmlns="[url]http://www.w3.org/1999/xhtml[/url]" >
  <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對象
  
  一、Application狀態
  1、應用程序級別的狀態存取(就是說服務器上的應用程序,各個客戶端都可以訪問它)
  2、變量狀態的存儲和提取
   存儲: Application["username"] = "xieex";
   提取: string strUserName = Application["username"];
  3、同時訪問要加鎖,防止併發衝突
   Application.Lock();
   Application.Unlock();
  Application是保存在服務器內存中的。
  參見實例(ApplicationState.aspx)
  該實例用於記錄訪問該頁面的訪問者個數,用Application存儲變量,這樣不會因爲一次會話結束而把訪問記錄清零。
  
  
  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)
   {
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章