【分析总结】ASP.NET中的状态管理原理
????? HTTP協議是介于請求、響應的斷開時網絡協議,與連接式的網絡協議不同,例如,與我們熟悉的TCP協議相比,客戶端與服務器并沒有持續的連接存在,在每一次會話之后,連接都會被斷開,在下一次請求的時候客戶端會重新與服務器建立連接進行會話。那么,服務器如何來跟蹤客戶端,在斷開的輕快下,客戶端又如何與服務器端保持會話呢?
????? 為了解決這個問題,在網站開發中,提供了大量的狀態管理技術來解決這個問題,在ASP.NET中,還提供了一些專用的技術,使得我們更加輕松的完成狀態管理服務。
?????
????? ·首先我們可以考慮form表單中提供的隱藏域。顧名思義,隱藏域就是表單中看不到的輸入項,他必須配合表單使用。雖然看不到,但是,在提交表單的時候,隱藏域中得信息將隨著表單一起被發送到服務器。隱藏域的使用方法如下:
<form method="post" action="hidden.aspx" id="form1">...
<input type="hidden" id="HiddenField1" name="HiddenField1" value="DebugLZQ"/>
...
</form>
????? 在ASP.NET中,可以通過HiddenField這個服務器控件來生成上述的HTML,這樣我們就可以在服務器上,通過面向對象的方式來獲取網頁中得隱藏域。
this.HiddenField1.value=this.TextBox1.Text;????? 在默認輕快下,ASP.NET表單將會提交到本頁面,所以,在提交表單的時候,保存在客戶端隱藏域中得信息將會發送回服務器。由于輕輕參數的name將會與服務器上頁面對象中隱藏域控件的id相匹配,這樣,在下一次請求的時候,在服務器上,我們就可以通過隱藏域控件的屬性獲得上一次請求中保存在隱藏域中得值。
?
this.TextBox1.Text=this.HiddenField1.value;????? 存在的問題:影藏域存在于網頁中得Form表單,當頁面關閉的時候,隱藏域中得信息將會丟失。所以不適合需要長期有效的狀態管理。
?????
????? ·為了能夠更加長久地保存用戶會話的狀態信息,Cookie被Netscape公司引入網站開發中。
????? 傳統上,網站是基于廣播模式的,也就是說,所有的用戶看到的內容都是一樣的,,如果對用戶提供一對一的服務,就必須能夠從用戶的請求中去別處不同的用戶。雖然通過隱藏域也能部分完成這個需求,但是,當用戶關閉瀏覽器的時候,隱藏域中保存的信息將會丟失,不能長久保存。Cookie允許用戶將自己的狀態信息以名值對的形式保存在客戶端。在Cookie有效的情況下,在用戶每次向這個服務器發出請求的時候都會自動附加在請求中,同時還允許設置Cookie保存在客戶端的時間,以便于在用戶關閉瀏覽器之后,還能繼續保存狀態信息。
????? 在HTTP協議中,通過在服務器的回應中增加Set-Cookie的回應頭,可以指示客戶端保存Cookie。
????? 瀏覽器會在特殊的位置來保存Cookie的內容,Cookie的內容不會在頁面上顯示出來,非常適合隱藏地保存狀態信息。
????? 在瀏覽器保存有Cookie的情況下,在以后的請求中,瀏覽器將會以請求頭的形式自動附加這個Cookie中保存的信息,以名值對的形式發送到服務器。
????? 這樣,服務器就可以獲得從前保存的狀態信息了。
????? 在ASP.NET中,服務器通過HttpCookie數據類型來處理在回應中生成Set-Cookie頭和在請求中的Cookie信息的問題。
public sealed class HttpCookie????? 配合HttpCookie,在HttpResponse中,通過Cookie集合屬性來表示準備生成回應中Set-Cookie的HttpCookie集合。這樣,在服務器上,指示客戶端生成Cookie的代碼如下所示:
HttpCookie cookie=new HttpCookie("DebugLZQ");cookie.Value=this.TextBox1.Text;
this.Reponse.Cookies.Add(cookie);
????? 對于請求中附帶的Cookie信息,HttpRequest通過其Cookies集合屬性表示為對象的形式,由于瀏覽器的請求中可能附帶有多個Cookie參數,可以通過Cookie的名字來獲取對應的Cookie參數。
HttpCookie cookie=new HttpCookie("DebugLZQ");if(cookie!=null)
{
this.Label1.Text=cookie.Value;
}
????? 在默認情況下創建的Cookie,將保存在瀏覽器的Cookie容器中,當瀏覽器關閉時,Cookie將一同被銷毀。Cookie的Expires屬性表示Cookie的過期時間。這是一個絕對過期時間,以格林威治標準時間的格式表示,到達這個時間之后,Cookie將會失效。為了能過長期使用保存在Cookie中的信息,可以將Cookie的Expires屬性設置為未來的一個更長的時間,在大道這個時間之前,Cookie將一直有效。例如,可以通過如下的語句將Cookie設置保存10分鐘。
cookie.Expires=DateTime.Now.AddMinutes(10.0);????? 注意,如果沒有設置過期時間,Cookie將會保存到瀏覽器關閉為止。
????? 可是,瀏覽器關閉之后,Cookie將保存在那里了?他是如何做到再次打開瀏覽器時,依然能夠取得Cookie中的值呢?
????? 在設置過期時間之后,瀏覽器會將這個Cookie保存在一個特定的文件夾中,Cookie文件時一個文本格式的文件。根據RFC2109的描述,每個客戶端最多保存300個Cookie,對于每個站點來說最多20個Cookie(實際上多數瀏覽器現在都比這個多,比如Firefox是50個),每個cookie最多4K,注意這里的4K根據不同的瀏覽器可能不是嚴格的4096。
?????
????? ·我們也可以通過在URL地址中嵌入信息來實現狀態管理,由于在向服務器發出請求的時候,URL地址將作為請求的一部分發送到服務器,這樣,可以從中提取出保存的信息。需要在URL地址中保存信息的時候,通過將信息以特殊的格式插入到URL地址中完成。
?????
????? ·使用隱藏域可以在表單中傳遞大量的數據,但是,直接保存在隱藏域中的信息必須是字符串形式的數據,這是HTML頁面的字符性質決定的。在ASP.NET服務器端處理的是以對象為表示形式的數據,如果這些對象可以被保存以便在后繼的訪問中使用,將大大方便服務器端的程序設計。在ASP.NET中,提供了基于隱藏域的增加對象序列化和反序列化支持的狀態管理機制,通過將服務器端的可序列化對象序列化為字符串的形式,然后,以隱藏域的形式保存在也賣弄的表單中,一般在后繼的請求中發送回服務器,最后通過反序列化操作還原為原來的對象,在ASP.NET中這個技術被稱為視圖狀態ViewState。
?????
????? ·視圖狀態ViewState為開發人員帶來便利,但是巨大的視圖狀態在服務器和瀏覽器之間的往返傳遞也帶來了繁重的網絡壓力,有的時候我們會禁用也賣弄的視圖狀態來提高訪問的效率。
????? 由于有些信息對付控件來說非常重要,所以,在禁用ViewState后,會造成有些控件功能的徹底失效,比如GridView的分頁功能。從ASP.NET 2 0開始,通過控件狀態來提供一種比視圖狀態更加安全的控件狀態ControlState的管理管理機制。控件狀態的使用類似于視圖狀態,但是,即使用戶關閉視圖狀態之后,也會仍然有效。
????? 類似于視圖狀態的LoadViewState和SaveViewState方法,控件狀態也是提供了一對這樣的方法,方法名稱分別為LoadControlState和SaveControlState,兵器也是在Control基類中提供。
????? 要使用控件狀態,首先需要在也賣弄上注冊需要使用的控件狀態。這個工作一般在控件的Init中進行,方法的參數就是要注冊的控件對象。
protected override void OnInit(EventArgs e){
base.OnInit(e);
page.RegisterRequiresControlState(this);
}
???? ?然后,在控件中使用LoadViewState和SaveViewState完成控件狀態的加載和保存即可。
?????
????? ·應用程序狀態HttpApplicationState的機制是比較簡單的,這是一個服務器端的全局的狀態管理。因為是服務器端的全局狀態管理,所以,不在涉及也賣弄和請求的處理過程,也不需要區分不同的會話或者用戶。為了方便保存多個不同的狀態,應用程序狀態Application派生自NameObjectCollectionBase,允許用戶通過一個字符串的名字來保存或提取相應的對象。
????? 應用程序狀態管理對象可以通過上下文對象獲取到,他的定義如下:
public HttpApplicationState Application{get;}????? 其中,HttpApplicationState的定義如下:
public sealed class HttpApplicationState:NameObjectCollectionBase????? 對于引用程序狀態對象來說,由于所有的請求都可能需要訪問這個對象,為了解決并發訪問的問題,同時還提供了線程的同步機制,通過鎖來同步對于這個集合的訪問。
public void Lock();public void UnLock();
????? HttpApplicationState類使用AllKeys和Count屬性以及Add、Clear、Get、GetKey、Remove、RemoveAt和Set方法來自動鎖定和解鎖。但是,如果需要對保存在全局應用程序狀態中的數據進行連續多次的訪問,通過顯式的Lock進行加鎖和UnLock進行解鎖有助于提高訪問效率。
????? 對于一個網站來說,存在一個HttpApplicationState對象管理狀態,這個對象隨著網站的啟動而穿件,當網站關閉的時候才會釋放,因此,通過Application保存的狀態信息會伴隨整個網站的生命周期,在不適用的時候,一定要及時釋放所用的空間。
?????
????? ·Session是一個歷史悠久的狀態管理技術,從ASP時代開始,就稱為了Web開發不可或缺的基本狀態管理技術。
????? 對于無狀態的HTTP來說,Session是一個服務器端的狀態管理方案,這個方案的特點在于每個客戶端都可以將實際的數據保存在服務器上,對于客戶端的數據,會生成一個對應的唯一的key。在服務器端保存數據之后,將用于取得所保存數據的key發送到客戶端。在后繼的請求中,客戶端將這個保存在客戶端的key發送回服務器端,在服務器上通過這個key來取得相應的數據。通常,我們稱這個key為SessionID。Session的工作原理如下:
????? 在一般輕快下,這個SessionID以Cookie的形式保存在瀏覽器中,在不適用Cookie的情況下,也可以將這個SessionID嵌入到訪問網站的URL地址中(前面講過)。
????? 在頁面對象或者HttpContext對象匯總,都有一個名為Session的屬性,在一次會話中,他們引用的是同一個對象,定義如下:
public HttpSessionState Session{get;}????? 在Sesion中,我們通常使用下面的方法來進行狀態管理:
public void Add(string name,Object value)public void Remove(string name);
public void Clear();
public void Abandon();
????? 這個HttpSessionState來自于SessionStateModule。在每次請求處理過程中,HttpApplication的請求的處理管道中會檢查當前請求的處理程序是否實現了接口IRequiresSessionState,如果實現的話,那么SessionStateModule將為這個請求分配HttpSessionState。
????? 需要注意的是,只有執行下面這樣的代碼片段后,才可以認為Session會話開始。
Session[“DebugLZQ”]=”some data”;????? Session字典通常包含Object類型,要向后讀取數據,需要將返回的值轉為為更具體的類型。
string data=Session[“DebugLZQ”] as string;????? Session_OnEnd事件標志著會話的結束,并用于執行中止該會話所需的所有清除代碼。
????? 如果會話超時或被放棄,下次訪問無狀態應用程序時,其會話ID不會發生改變。進過設計后,即使會話狀態過期,會話ID也能持續到瀏覽器會話結束。也就是說,只要瀏覽器實例相同,就始終使用同一個會話ID表示多個會話。
????? 對于Session來說,關鍵的問題在于Session過期指的是某個會話整個Session的過期,并不針對其中某個數據的過期,要么整個Session過期后丟棄掉,要么所有的數據都被保留下來,在每一次請求的時候都會被加載到內存中,這可能會造成內存的浪費。所以,在使用Session的時候,我們必須要謹慎選擇保存的數據。
?
????? ·HttpContext狀態可能是所有狀態管理中最簡單的狀態管理,也是最有效的狀態管理方式,HttpContext基于HttpApplication的處理管道,由于HttpContext對象貫穿整個處理過程,所以,可以從HttpApplication處理管道的前端將狀態數據傳遞到管道的后端,完成狀態的傳遞任務。
????? 在HttpContext中通過Items屬性允許我們將需要傳遞的數據進行存取,這個屬性的定義如下:
public IDictionary items{get;}????? 可以看到這是一個字典,我們可以通過鍵值對的形式來使用它。
?
????? ·緩存管理Cache是ASP.NET中更加強大的狀態管理。這是在 ASP.NET中唯一可以根據服務器的使用情況,動態管理內存使用的狀態管理干干。允許我們針對每一個緩存的數據,單獨設置數據的有效條件,使得內存的使用效率最大化。Cache屬于公共的狀態管理,我們通過每個緩存數據的鍵值字符串來區分緩存的數據(不詳細解釋了~)。
?
???·Memcached是dangga.com開發的一套分布式內存對象緩存系統。Memcached是分布式的,基于網絡連接(當然他也可以使用localhost)方式完成服務,本身它是一個獨立于應用的程序或守護進程。
??????Memcached在很多時候都是作為數據庫前端Cache使用的。因為他比數據庫少了很多SQL解析、磁盤操作等開銷,而且它是使用內存來管理數據的,所以他可以提供比直接讀取數據庫更好的性能。在大型系統中,訪問同樣的數據時很頻繁的,Memcached可以大大降低數據庫壓力,是系統執行效率提升。
?
????? 【請點擊下面的“綠色通道”-“關注DebugLZQ”,與DebugLZQ一起學習進步~】
轉載于:https://www.cnblogs.com/DebugLZQ/archive/2012/01/04/2311198.html
總結
以上是生活随笔為你收集整理的【分析总结】ASP.NET中的状态管理原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql里的日期类型 和JPA里@Te
- 下一篇: sql server 2000 删除重复