HiddenFIEld控件顧名思義就是隱藏輸入框的服務器控件,它能讓你保存那些不需要顯示在頁面上的且對安全性要求不高的數據。也許這個時候應該有這麼一個疑問,為什麼有了ViewState、Session和Cookie等狀態保存機制,還需要用起HiddenFIEld呢?
增加HiddenField,其實是為了讓整個狀態管理機制的應用程度更加全面。因為不管是ViewState、Cookie還是Session,都有其失效的時候,比如用戶因某種需求要求設置ViewState為false,或者環境條件限制使用Cookie,或者用戶長時間沒有動作導致Session過期等等,那這個時候HiddenFIEld無疑是最佳選擇。
HiddenFIEld控件的作用簡單的說是用於存儲需要在向服務器的發送間保持的值。它作為 <input type= "hidden"/> 元素呈現,並且通過添加runat=”server”就可以使它成為標准的Html服務器控件。下面列出的是ASP.Net HiddenFIEld Web服務器控件可以使用的屬性和事件。
<ASP:HiddenFIEld
EnableTheming="True|False"
EnableVIEwState="True|False"
ID="string"
OnDataBinding="DataBinding event handler"
OnDisposed="Disposed event handler"
OnInit="Init event handler"
OnLoad="Load event handler"
OnPreRender="PreRender event handler"
OnUnload="Unload event handler"
OnValueChanged="ValueChanged event handler"
runat="server"
SkinID="string"
Value="string"
Visible="True|False"
/>
因為 HiddenFIEld 的值將呈現給客戶端浏覽器,所以它不適用於存儲安全敏感的值。若要為 HiddenField 控件指定值,請使用 Value 屬性,請注意是Value而不是Text。事實上HiddenFIEld並沒有Text屬性,這和DropDownList、CheckBoxList等標准按鈕的屬性命名方式一致。在標准的屬性命名方式中,Text的值是呈現給用戶看到的,而Value的值則是通長是通過代碼進行控制的。例如你可以讓DropDownList的Text屬性顯示用戶名而讓它的Value存儲用戶的編號。
下面的代碼顯示的是改控件的基本使用。
<Html>
<head>
<script language="C#" runat="server">
void Button1_Click(object sender, EventArgs e)
{
if (HiddenFIEld1.Value == String.Empty)
HiddenFIEld1.Value = "0";
HiddenField1.Value = (Convert.ToInt32(HiddenFIEld1.Value)+1).ToString();
Label1.Text = HiddenFIEld1.Value;
}
</script>
</head>
<body>
<h3><font face="Verdana">HiddenFIEld</font></h3>
<form runat=server>
<ASP:HiddenField id=HiddenFIEld1 runat=Server />
<ASP:Button id=Button1 Text="單擊按鈕" onclick="Button1_Click" runat="server" />
單擊 <ASP:Label id=Label1 Text="0" runat=server /> 次
</form>
</body>
</Html>
在上面代碼中, <ASP:HiddenField id=HiddenFIEld1 runat=Server />就定義了一個隱藏控件在按鈕的單擊事件裡計算用戶單擊的次數,並將改次數賦值給Label1。
你可以將上面代碼中的 <ASP:HiddenField id=HiddenField1 runat=Server />改為<input type=hidden id=HiddenFIEld1 runat=Server >也是可以的
在使用上面代碼裡,如果你從浏覽器裡查看源代碼會得到如下的信息:
<form name="Form1" method="post" action="Default.ASPx" id="Form1">
這是因為HiddenField是通過HTTP協議進行傳遞數據的,所以如果你通過" method="get"或者鏈接打開新的窗體頁,那麼HiddenFIEld並不可用。
另外,HiddenFIEld並不是取代Session來維護狀態的,在上面例子裡,雖然你點擊一次按鈕可以顯示你點擊的次數但是並不是說它可以記錄你的狀態信息。如果你重新打開浏覽器那麼你看到的此處仍然是0而不是3。
HiddenFIEld事件
HiddenFIEld較為常用的是ValueChanged事件,該事件在Value值發生改變時觸發該事件。然而在實際使用時,要知道頁面記載順序。在頁面回傳過程中,具體的頁面周期你可以到如下網站查看
http://msdn2.microsoft.com/zh-cn/library/ms178472.ASPx
下面的例子說明了這個問題
<head>
<script runat="server" language="c#">
protected void Page_Load(object sender, EventArgs e)
{ Response.Write("<p>頁面的Page_Load事件觸發,觸發時間是:" + DateTime.Now.ToString());
if (HiddenFIEld1.Value == String.Empty)
HiddenFIEld1.Value = "0"; }
protected void Button1_Click(object sender, EventArgs e)
{ Response.Write("<p>Button1_Click為改變Hidden的值前事件觸發,觸發時間是:" + DateTime.Now.ToString());
HiddenField1.Value = (Convert.ToInt32(HiddenFIEld1.Value) + 1).ToString();
Label1.Text = HiddenFIEld1.Value;
}
protected void HiddenFIEld1_ValueChanged(object sender,EventArgs e)
{ Response.Write("<p>HiddenFIEld的 ValueChanged事件觸發,觸發時間是:" + DateTime.Now.ToString()); }
</script>
</head>
<body>
<form id="form1" runat="server">
<div> <ASP:HiddenField ID="HiddenField1" runat="server" OnValueChanged="HiddenFIEld1_ValueChanged" />
</div> <asp:Label ID="Label1" runat="server" Text="Label"></ASP:Label>
<br /> <ASP:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</form></body>
</Html>
在這個例子裡,我們想要的結果是:當用戶單擊按鈕時,通過按鈕的Button1_Click事件更改HiddenField1的Value,然後再觸發HiddenField1的HiddenFIEld1_ValueChanged事件,然而事實真的如此嗎?
運行上面的代碼,得到的結果正如你看到的,每次單擊時,Button確實改變了HiddenField的值,但是我們在HiddenFIEld1_ValueChanged裡定義的輸出並沒有執行,換句話說頁面並沒有執行ValueChanged事件
要理解這個問題還需要了解頁面的聲明周期,在頁面周期過程中,你可以看到在Page_Init裡是讀取或初始化控件屬性,然後再是Control events。
這裡的事件意思是說: 在Page_Init事件裡,Web頁面會接受用戶回傳的數據,例如將 <span id="Label1">Label</span>賦值給ID為Label1的Text屬性,將 <input type="hidden" name="HiddenField1" id="HiddenField1" value="0" />的value值賦值給HiddenField1的Value屬性。等所有初始化完畢了,頁面才開始執行控件的事件--Button1_Click,在Button事件裡將HiddenFIEld的Value值改變。那麼這裡既然已經將Value值改變為什麼沒有執行ValueChanged事件呢?
此時,雖然這裡已經將Value值改變,但是在Page_Init裡保存的這是因為當前單擊Button按鈕時,雖然改變了HiddenField但同樣又一次觸發了頁面的回復,也就是雖然在上一此HiddenValue的值為0,而此次將其值改為1,但是在頁面回傳後,由於ViewState會保存上次的裝(這裡是1),所以在Page_Init裡,認為HiddenFIEld的初始值為1,而本次還是1,使得它感覺數據沒有變化,所以仍然不會觸發ValueChanged事件
當然,你可以禁用HiddenField來進行處理,就可以執行ValueChanged事件,但是事實上你禁用ViewState後,頁面不再保存ViewState的值使得頁面認為每一次請求HiddenFIEld的都是新的,例如如下代碼:
你並沒有改變HiddenfIEld的值,但是仍然每次都執行。
<%@ Page EnableVIEwState="false" %>
<head>
<script runat="server" language="c#">
protected void Page_Load(object sender,EventArgs e)
{
if (HiddenFIEld1.Value == String.Empty)
HiddenFIEld1.Value = "111";
}
protected void Button1_Click(object sender, EventArgs e)
{ // HiddenField1.Value = (Convert.ToInt32(HiddenFIEld1.Value) + 1).ToString();
Label1.Text = TextBox1.Text; }
protected void HiddenFIEld1_ValueChanged(object sender, EventArgs e)
{ Response.Write("Changed." + DateTime.Now.ToString());
Response.Write(HiddenFIEld1.Value);
Response.Write(TextBox1.Text); }
</script>
</head>
<body>
<form id="form1" runat="server"> <div>
<ASP:HiddenField ID="HiddenField1" runat="server" OnValueChanged="HiddenFIEld1_ValueChanged" />
</div>
<asp:Label ID="Label1" runat="server" Text="Label"></ASP:Label>
<br />
<asp:TextBox runat=server ID=TextBox1></ASP:TextBox>
<ASP:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</form>
</body>
</Html>
利用HiddenFile 並結合ASP.Net2.0提供的“交叉Cross Page”頁面可以實現頁面數據的傳遞,該情況針對這樣的一種方案:
在一個注冊頁面裡,需要用戶輸入數據,由於備注一欄的數據可能很多,可以在新窗口可以利用類似FreeTextBox的控件讓用戶
格式化文本,並在輸入完畢後,返回原注冊頁面。關於這種情況,以後會介紹