asp.net|控制項 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" 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="單擊按鈕" 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" 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" Text="Button" /> </form> </body> </html> |
利用HiddenFile 並結合ASP.NET2.0提供的“交叉Cross Page”頁面可以實現頁面資料的傳遞,該情況針對這樣的一種方案:
在一個註冊頁面裡,需要使用者輸入資料,由於備忘一欄的資料可能很多,可以在新視窗可以利用類似FreeTextBox的控制項讓使用者
格式化文本,並在輸入完畢後,返回原註冊頁面。關於這種情況,以後會介紹。