推薦:用ASP程序實現網站在線人數統(tǒng)計在瀏覽網頁的時侯,常??梢钥匆娨恍?ldquo;當前網站上的人數是XXX人”的在線人數同計。如何用ASP來做一個呢?首先,分析一下它的做法,一般來說,這些線上人數統(tǒng)計都是指一個時段內的
基本概念
控件狀態(tài)-為了讓控件正常工作,有時需要存儲控件狀態(tài)數據。例如,如果編寫了一個自定義控件,其中具有顯示不同信息的不同選項卡,為使該控件如預期一樣工作,控件需要知道在往返過程中選擇的是哪個選項卡。ViewState 屬性可用于此目的,但開發(fā)人員可能在頁級別關閉了視圖狀態(tài),從而有效地中斷控件。為解決此問題,ASP.NET 頁框架在 ASP.NET 2.0 版中公開了一種稱為控件狀態(tài)的新功能。
ControlState 屬性允許保持特定于控件的屬性信息,不像 ViewState 屬性一樣可以關閉。若要使用控件狀態(tài),控件必須在初始化過程中調用 RegisterRequiresControlState 方法,然后重寫 SaveControlState 和 LoadControlState 方法。
視圖狀態(tài)-視圖狀態(tài)是 ASP.NET 頁框架默認情況下用于保存往返過程之間的頁和控件值的方法。當呈現頁的 HTML 形式時,需要在回發(fā)過程中保留的頁的當前狀態(tài)和值將被序列化為 Base64 編碼的字符串,并輸出到視圖狀態(tài)的隱藏字段中。通過實現自定義的 PageStatePersister 類以存儲頁數據,您可以更改默認行為并將視圖狀態(tài)存儲到另一個位置(如 SQL Server 數據庫)。有關將頁狀態(tài)存儲到流上而不是隱藏的頁字段中的示例,請參見 視圖狀態(tài)持久性機制的示例。
您可以通過使用頁的 ViewState 屬性將往返過程中的數據保存到 Web 服務器來利用自己的代碼訪問視圖狀態(tài)。ViewState 屬性是一個包含密鑰/值對(其中包含視圖狀態(tài)數據)的字典。
各自的優(yōu)勢與劣勢
視圖狀態(tài)
使用視圖狀態(tài)的優(yōu)點:
·不需要任何服務器資源 視圖狀態(tài)包含在頁代碼內的結構中。
·實現簡單 視圖狀態(tài)無需使用任何自定義編程。默認情況下對控件啟用狀態(tài)數據的維護。
·增強的安全功能 視圖狀態(tài)中的值經過哈希計算和壓縮,并且針對 Unicode 實現進行編碼,其安全性要高于使用隱藏域。
使用視圖狀態(tài)的缺點
·性能注意事項 由于視圖狀態(tài)存儲在頁本身,因此如果存儲較大的值,用戶顯示頁和發(fā)送頁時的速度可能會減慢。尤其是對移動設備,其帶寬通常是有限的。
·設備限制 移動設備可能沒有足夠的內存容量來存儲大量的視圖狀態(tài)數據。
·潛在的安全風險 視圖狀態(tài)存儲在頁上的一個或多個隱藏域中。雖然視圖狀態(tài)以哈希格式存儲數據,但它可以被篡改。如果直接查看頁輸出源,可以看到隱藏域中的信息,這導致潛在的安全性問題。
控件狀態(tài)
使用控件狀態(tài)的優(yōu)點:
·不需要任何服務器資源 默認情況下,控件狀態(tài)存儲在頁上的隱藏域中。
·可靠性 因為控件狀態(tài)不像視圖狀態(tài)那樣可以關閉,控件狀態(tài)是管理控件的狀態(tài)的更可靠方法。
·通用性 可以編寫自定義適配器來控制如何存儲控件狀態(tài)數據和控件狀態(tài)數據的存儲位置。
使用控件狀態(tài)的缺點:
·需要一些編程 雖然 ASP.NET 頁框架為控件狀態(tài)提供了基礎,但是控件狀態(tài)是一個自定義的狀態(tài)保持機制。為了充分利用控件狀態(tài),您必須編寫代碼來保存和加載控件狀態(tài)。
控件狀態(tài)與視圖狀態(tài)示例
此示例演示如何創(chuàng)建一個名為 IndexButton 的自定義控件,該控件使用控件狀態(tài)在多個頁請求間維護關鍵狀態(tài)信息。在 ASP.NET 2.0 版中引入的控件狀態(tài)與視圖狀態(tài)類似,但功能上獨立于視圖狀態(tài)。網頁開發(fā)人員可能會出于性能原因而禁用整個頁面或單個控件的視圖狀態(tài),但他們不能禁用控件狀態(tài)??丶顟B(tài)是專為存儲控件的重要數據(如一個頁面控件的頁數)而設計的,回發(fā)時必須用到這些數據才能使控件正常工作(即便禁用視圖狀態(tài)也不受影響)。默認情況下,ASP.NET 頁框架將控件狀態(tài)存儲在頁的一個隱藏元素中,視圖狀態(tài)也同樣存儲在此隱藏元素中。即使禁用視圖狀態(tài),或是使用 Session 管理狀態(tài)時,頁面中的控件狀態(tài)仍會傳輸至客戶端,然后返回到服務器。在回發(fā)時,ASP.NET 會對隱藏元素的內容進行反序列化,并將控件狀態(tài)加載到每個注冊過控件狀態(tài)的控件中。
此示例闡釋了一個同時在控件狀態(tài)和視圖狀態(tài)中保存狀態(tài)的自定義控件。在此示例中,IndexButton 控件派生自 Button 類,還定義了一個 Index 屬性,并將該屬性保存在控件狀態(tài)中。為了進行比較,IndexButton 還定義了一個 IndexInViewState 屬性,該屬性存儲在 ViewState 字典中。為了了解控件狀態(tài)和視圖狀態(tài)之間的差異,請使用本文附帶的程序來演示 IndexButton 控件。
IndexButton控件源碼
using System;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomerControls
{
[
AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
ToolboxData("<{0}:IndexButton runat=/"server/"> </{0}:IndexButton>")
]
public class IndexButton : Button
{
private int indexValue;
[
Bindable(true),
Category("Behavior"),
DefaultValue(0),
Description("The index stored in control state.")
]
public int Index
{
get
{
return indexValue;
}
set
{
indexValue = value;
}
}
[
Bindable(true),
Category("Behavior"),
DefaultValue(0),
Description("The index stored in view state.")
]
public int IndexInViewState
{
get
{
object obj = ViewState["IndexInViewState"];
return (obj == null) ? 0 : (int)obj;
}
set
{
ViewState["IndexInViewState"] = value;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override object SaveControlState()
{
//調用基類的方法,從基類得到控件狀態(tài)的基值
//如果indexValue不等于并且基類的控件狀態(tài)不為null
//使用Pair作為便利的數據結構來高效保存(和在LoadControlState方法中還原)
//由兩部分組成的控件狀態(tài)
object obj = base.SaveControlState();
if (indexValue != 0)
{
if (obj != null)
{
return new Pair(obj, indexValue);
}
else
{
return (indexValue);
}
}
else
{
return obj;
}
}
protected override void LoadControlState(object state)
{
if (state != null)
{
Pair p = state as Pair;
if (p != null)
{
base.LoadControlState(p.First);
indexValue = (int)p.Second;
}
else
{
if (state is int)
{
indexValue = (int)state;
}
else
{
base.LoadControlState(state);
}
}
}
}
}
}
代碼討論
IndexButton 控件的實現闡釋了三個任務,必須執(zhí)行這三個任務才能使控件參與控件狀態(tài):
· 重寫 OnInit 方法并調用 RegisterRequiresControlState 方法向頁面注冊,以參與控件狀態(tài)。必須針對每個請求完成此任務。
· 重寫 SaveControlState 方法,以在控件狀態(tài)中保存數據。
· 重寫 LoadControlState 方法,以從控件狀態(tài)加載數據。此方法調用基類方法,并獲取基類對控件狀態(tài)的基值。如果 indexValue 字段不為零,而且基類的控件狀態(tài)也不為空,Pair 類便可作為方便的數據結構使用,用來保存和還原由兩部分組成的控件狀態(tài)。
分析總結
從MSDN上的一系列的技術參考來看,ControlState應該是主要在自定義控件上使用,“ASP.NET 頁框架提供了 ControlState 屬性作為在服務器往返過程中存儲自定義控件數據的方法”,這是MSDN上的原句,ASP.NET2.0只是為ControlState提供了一個基礎,當ControlState是一個自定義的狀態(tài)保持機制,也就是說保持狀態(tài)的機制需要你開發(fā)人員自己去完成,而不像ViewState,它有自己默認的狀態(tài)保持機制。在自定義控件使用ControlState也許才是微軟本意了,為的就避免在頁面級別禁用掉ViewState后,自定義控件還能正常運行。當然這里的意思就是,某些控件的正確運行是依賴于它的狀態(tài)信息的,在ASP.NET1.1中,如果禁用了ViewState,這樣的控件就無法正確運行了。但引入了ControlState后就不同了,因為ControlState是禁用不掉的。
所以微軟才提醒開發(fā)人員“請僅對那些在回發(fā)過程中對控件至關重要的少量關鍵數據使用控件狀態(tài),而不要將控件狀態(tài)作為視圖狀態(tài)的備用選項使用”。明確說出,ControlState和ViewState完全是兩個東西,雖然它們可以完成相同的任務,新推出的ControlState既不是用來替代ViewState也不是用來做ViewState的替補。它的使命是彌補ViewState的所不能完成的任務,讓開發(fā)人員開發(fā)出更加健壯的控件。例如說,開發(fā)的自定義控件某個狀態(tài)是至關重要的,缺少它就自定義控件不能正常工作,那么ControlState就該上場了。而且ControlState是自定義的狀態(tài)保持機制,也限制了ControlState自由的使用,你不但要在OnInit 方法并調用 RegisterRequiresControlState 方法向頁面注冊,而且要重寫SaveAdapterControlState(),LoadAdapterControlState(object state)兩個方法自己去實現要保存什么,怎樣保存。根據我現在的理解,如果你需要保存該控件的10種不同狀態(tài),那你就得一一保存,再一一加載上去。從這點也就看出了微軟的初衷了,那不是很明顯嗎,如果不需要ControlState那就不使用它吧,否則怎么它什么都讓我們開發(fā)人員去做呢?
這只是基礎了,剛才我說了,似乎微軟也是這么說的,ControlState針對的是自定義控件,其實我們真的要去開啟基本控件例如Label控件的ControlState,微軟也是允許的,這就是稍深的內容了,這就涉及到控件適配器了(ControlAdapter)。如果需要了解這方面的內容,請看用控件適配器開啟基本控件的ControlState。http://sifang2004.VeVb.com/archive/2006/06/01/415288.html
附錄
為了更加充分理解上面的內容,需要對以下內容有個了解:
Pair 類
用作存儲兩個相關對象的基本結構。它是在整個 ASP.NET 中(在如頁面狀態(tài)管理任務期間或配置節(jié)處理程序的過程中)有多種用法的實用工具類??梢栽谧约旱拇a中需要包含兩個相關對象的結構的任意位置和不一定需要數據綁定的位置使用 Pair 類。Pair 類不將其對象引用 First 和 Second 封裝在屬性中;該類直接將它們作為公共類字段公開到所有調用代碼。
Pair 類在頁狀態(tài)保留實現中有多種用法。最常見的用法是同時作為 ViewState 和 ControlState 集合的容器。在這種情況下,First 屬性用于 ViewState,而 Second 用于 ControlState。
PageStatePersister 類
HTTP 請求和響應原本是無狀態(tài)的。要在 HTTP 請求之間保持狀態(tài)信息,ASP.NET 服務器頁可以存儲 Page 狀態(tài)。此狀態(tài)稱為視圖狀態(tài),它包含頁和控件設置及數據,這些設置和數據使得頁和控件看起來就像在上一次將它們提交到服務器然后又返回到客戶端時,用戶所看到并與之交互的頁和控件一樣。有幾種機制可在對相同頁的連續(xù)請求之間存儲視圖狀態(tài)。PageStatePersister 抽象類表示這些狀態(tài)信息存儲機制的基類。
要在不能支持現有視圖狀態(tài)持久性機制的客戶端上保留視圖狀態(tài),可以擴展 PageStatePersister 類,引入您自己的視圖狀態(tài)持久性方法,并且可以使用頁適配器將 ASP.NET 應用程序配置為根據為其提供頁的客戶端的類型使用不同的視圖狀態(tài)持久性機制。從 PageStatePersister 類派生的類必須重寫 Save 抽象方法,以便在持久性介質中存儲視圖狀態(tài)和控件狀態(tài),同時重寫 Load 方法以提取狀態(tài)信息。如果想知道如何寫PageStatePersister的派生類,請參考視圖狀態(tài)持久性機制。
分享:ASP例子:ASP把漢字轉化為拼音的函數拼音不夠全面,不推薦使用,學習一下方法而已~ 以下為引用的內容:<% Set d = CreateObject("Scripting.Dictionary") d.add &quo
新聞熱點
疑難解答
圖片精選