You have a page with a state
whose value the page needs to remember
between postbacks
to determine how the page should
be displayed.
Use the RegisterHiddenField
method of
the Page
object
to create a hidden text field in the rendered page.
Nothing special is required in the .aspx
file.
Instead, in the code-behind class for the page, use the .NET language
of your choice to:
Programmatically insert a hidden text field into the form using the
RegisterHiddenField
method of the
Page
object.
Use this field to store the value of the state you wish to preserve
between postbacks
.
Access the hidden text field on subsequent submissions of the page to the server.
Figure 6-3 shows the output of a simple form that
preserves the page state using a hidden field. Clicking the Prev/Next
buttons decrements/increments the value in the hidden field by one.
Example 6-11 shows the .aspx
file that produces the form. Example 6-12
and Example 6-13 show the companion VB and C#
code-behind files that demonstrate how to access the application
state data.
An approach we favor for remembering the current state of a value
between postbacks
to the server involves
programmatically inserting one or more hidden text fields into a
form.
A similar technique is commonly used by classic ASP developers, who
explicitly place a hidden text field in the form and then set its
value in the page code. You can use the same technique in ASP.NET
pages. However, ASP.NET, unlike ASP, lets you programmatically insert
hidden text fields into a form at runtime. This has two significant
advantages. First, all code that you write is kept in the
code-behind, allowing the .aspx
file to contain
only the presentation aspects (hidden fields contain no user
interface). Second, the hidden fields are completely decoupled from
the .aspx
file. Because no hidden fields are
explicitly placed in the .aspx
file, you do not
have the maintenance issues associated with placing the server
control in the .aspx
file and then declaring it
in the code-behind.
One negative aspect of using hidden fields for storing state data is
the data is stored in plain text. If you do not want the data to be
readily visible in the rendered HTML, you should store the data in
the ViewState
instead, as described in
Recipe 6.4.
As an example of when you might use hidden fields, suppose your
application supports complex sorting within a
DataGrid
, such as a two-way sort that involves
both ascending and descending columns and might even be supported by
your own sorting expressions. You can use hidden fields to maintain
information about how a user has performed a specific sort so that
you can preserve the user’s sorting order and choice
of sorted columns.
Our example that illustrates the solution is kept relatively simple to focus on the concept of storing information in hidden fields each time a page is submitted to the server. The example programmatically inserts a single hidden field into a form and then increments or decrements its value based on the button clicked by the user.
Because the hidden field is accessed from many points in the
code-behind, a constant at the class level,
PAGE_STATE
, defines the name of the hidden field
that is programmatically inserted into the rendered page. This avoids
hardcoding the hidden field name throughout the code and the
associated maintenance issues.
In the Page_Load
method,
updatePage
, which is the method used to update the
page based on the page state, is called passing a value of 0 as the
initial page state value.
In the updatePage
method, a label
is updated to indicate the current
state value. After updating the page to reflect the current page
state, the RegisterHiddenField
method of the
Page
object is used to save the page state value
in the rendered page.
The rendered page contains the following hidden form variable that
can be retrieved when the page is submitted to the server. The name
is set to the value of the PAGE_STATE
constant,
and the value is set to the current page state:
<input type="hidden" name="PageState" value="0" />
Hidden fields always store the value as a string. This requires any
data saved using the technique to be converted to a string when the
RegisterHiddenField
method is called.
In this example, two buttons are provided to increment and decrement
the page state, respectively. An event handler is added in the
code-behind for each of the button click events. The event handler
for the increment button is called
btnNextState_Click
; the event handler for the
decrement button is btnPrevState_Click
. In the
event handlers, the current page state is retrieved from the hidden
field, adjusted as required, and then the
updatePage
method is again called to update the
page and save the new page state value in the form when the page is
rendered.
Even though the example presented here is simplistic, it nonetheless demonstrates how easy ASP.NET has made it to persist information that is needed for each round trip between the server and the client. For an example of persisting more complex data between page submittals, refer to Recipe 6.4.
Example 6-11. Maintaining page state with hidden values (.aspx)
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH06HiddenValuesVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH06HiddenValuesVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Hidden Values</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmStateHiddenValues" method="post" runat="server"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Maintaining Page State With Hidden Fields (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <table width="30%" align="center" id="tabState" runat="server"> <tr class="MenuItem"> <td>Current Page State: </td> <td><asp:Label ID="labPageState" Runat="server" /></td> </tr> <tr> <td colspan="2" align="center"> <br /> <asp:ImageButton ID="btnPrevState" Runat="server" ImageUrl="images/buttons/button_prev.gif" /> <asp:ImageButton ID="btnNextState" Runat="server" ImageUrl="images/buttons/button_next.gif" /> </td> </tr> </table> </td> </tr> </table> </form> </body> </html>
Example 6-12. Maintaining page state with hidden values code-behind (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH06HiddenValuesVB.aspx.vb ' ' Description: This module provides the code behind for ' CH06HiddenValuesVB.aspx ' '***************************************************************************** Namespace ASPNetCookbook.VBExamples Public Class CH06HiddenValuesVB Inherits System.Web.UI.Page 'controls on the form Protected tabState As System.Web.UI.HtmlControls.HtmlTable Protected labPageState As System.Web.UI.WebControls.Label Protected WithEvents btnPrevState As System.Web.UI.WebControls.ImageButton Protected WithEvents btnNextState As System.Web.UI.WebControls.ImageButton'The following variable defines the name of the hidden field in the
'form used to track the page state
Private PAGE_STATE As String = "PageState"
'************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load If (Not Page.IsPostBack( )) Then'not a postback so initialize the page state to 0
updatePage(0)
End If End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: btnPrevState_Click ' ' DESCRIPTION: This routine provides the event handler for the previous ' state button click event. It is responsible for setting ' the page state back one state. '-------------------------------------------------------------------------Private Sub btnPrevState_Click(ByVal sender As Object, _
ByVal e As System.Web.UI.ImageClickEventArgs) _
Handles btnPrevState.Click
Dim pageState As Integer
pageState = CInt(Request.Form(PAGE_STATE))
pageState -= 1
updatePage(pageState)
End Sub 'btnPrevState_Click
'************************************************************************* ' ' ROUTINE: btnNextState_Click ' ' DESCRIPTION: This routine provides the event handler for the next ' state button click event. It is responsible for setting ' the page state ahead one state. '-------------------------------------------------------------------------Private Sub btnNextState_Click(ByVal sender As Object, _
ByVal e As System.Web.UI.ImageClickEventArgs) _
Handles btnNextState.Click
Dim pageState As Integer
pageState = CInt(Request.Form(PAGE_STATE))
pageState += 1
updatePage(pageState)
End Sub 'btnNextState_Click
'************************************************************************* ' ' ROUTINE: updatePage ' ' DESCRIPTION: This routine updates the page for the passed page state. '-------------------------------------------------------------------------Private Sub updatePage(ByVal pageState As Integer)
'update the current page state display
labPageState.Text = pageState.ToString( )
'register the hidden field used to persist the current page state
RegisterHiddenField(PAGE_STATE, _
pageState.ToString( ))
End Sub 'updatePage
End Class 'CH06HiddenValuesVB End Namespace
Example 6-13. Maintaining page state with hidden values code-behind (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH06HiddenValuesCS.ascx.cs // // Description: This module provides the code behind for // CH06HiddenValuesCS.ascx // //**************************************************************************** using System; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples { public class CH06HiddenValuesCS : System.Web.UI.Page { // controls on the form protected System.Web.UI.HtmlControls.HtmlTable tabState; protected System.Web.UI.WebControls.Label labPageState; protected System.Web.UI.WebControls.ImageButton btnPrevState; protected System.Web.UI.WebControls.ImageButton btnNextState;// The following variable defines the name of the hidden field in the
// form used to track the page state
private String PAGE_STATE = "PageState";
//************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { // wire the next and prev button click event handlers this.btnPrevState.Click += new ImageClickEventHandler(this.btnPrevState_Click); this.btnNextState.Click += new ImageClickEventHandler(this.btnNextState_Click); if (!Page.IsPostBack) {// not a postback so initialize the page state to 0
updatePage(0);
} } // Page_Load //************************************************************************ // // ROUTINE: btnPrevState_Click // // DESCRIPTION: This routine provides the event handler for the // previous state button click event. It is responsible // for setting the page state back one state. //------------------------------------------------------------------------private void btnPrevState_Click(Object sender,
System.Web.UI.ImageClickEventArgs e)
{
int pageState;
pageState = Convert.ToInt32(Request.Form[PAGE_STATE]);
pageState -= 1;
updatePage(pageState);
} // btnPrevState_Click
//************************************************************************ // // ROUTINE: btnNextState_Click // // DESCRIPTION: This routine provides the event handler for the // next state button click event. It is responsible // for setting the page state back one state. //------------------------------------------------------------------------private void btnNextState_Click(Object sender,
System.Web.UI.ImageClickEventArgs e)
{
int pageState;
pageState = Convert.ToInt32(Request.Form[PAGE_STATE]);
pageState += 1;
updatePage(pageState);
} // btnNextState_Click
//************************************************************************ // // ROUTINE: updatePage // // DESCRIPTION: This routine updates the page for the passed page state. // //------------------------------------------------------------------------private void updatePage(int pageState)
{
// update the current page state display
labPageState.Text = pageState.ToString( );
// register the hidden field used to persist the current page state
RegisterHiddenField(PAGE_STATE,
pageState.ToString( ));
} // updatePage
} // CH06HiddenValuesCS }