Lesson 3: Maintaining State Information
In this lesson, you ll learn how to retain data on a Web form between
After this lesson, you will be able to
Choose from the different ways to save data on a Web form based on your needs
Transfer data between Web forms with query strings
Save items on the client as cookies
Store page data in a Web form s ViewState property
Keep application-wide
Structure access to Application and Session state variables to avoid programming errors
Estimated lesson time: 30 minutes
Overview of Levels of State
As explained in Chapter 2, Creating Web Forms Applications, Web forms are created and
Use this object to retrieve public
Use these strings to pass information between requests and responses as part of the Web address. Query strings are visible to the
Use cookies to store small amounts of information on a client. Clients might
ASP.NET stores items added to a page s ViewState property as hidden fields on the page.
Use Session state variables to store items that you want keep local to the current session (single user).
Use Application state variables to store items that you want be available to all users of the application.
Using Context.Handler
Ordinarily the members of one Web form are unavailable from a subsequently displayed Web form. However, when navigating between Web forms using the
Transfer
or
Execute
method, you can retrieve read-only properties from the previous Web form the first time a
For example, the following code declares a public property named Value that returns the data entered in a text box on the Context1 Web form:
Visual Basic .NET
Public Class Context1 Inherits System.Web.UI.Page ' Create a property to return the value of a text box. Friend ReadOnly Property Value() As String Get Return txtValue.Text End Get End Property Private Sub butNext_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles butNext.Click ' Transfer to thenext page. Server.Transfer("Context2.aspx") End Sub End Class
Visual C#
public class Context1 : System.Web.UI.Page { // Create a property to return the value of a text box. internal string Value { get { return txtValue.Text; } } private void butNext_Click(object sender, System.EventArgs e) { // Transfer to the next page. Server.Transfer("Context2.aspx"); } }
When the user clicks the Button control, he or she is transferred to the Context2 Web form, which retrieves the previous Web form s
Context.Handler
object, coerces that object to the previous Web form s type, and then
Visual Basic
Public Class Context2 Inherits System.Web.UI.Page Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' The first time this page is displayed If Not IsPostBack Then ' Declare an object with the previous page's type. Dim LastPage As Context1 ' Convert the context handler to the previous page's type. LastPage = CType(Context.Handler, Context1) ' Display the value from the page's Value property. lblValue.Text = LastPage.Value End If End Sub End Class
Visual C#
public class Context2 : System.Web.UI.Page { private void Page_Load(object sender, System.EventArgs e) { if (!IsPostBack) { // Declare an object using the previous page's type. Context1 LastPage; // Coerce the Context.Handler object to the page's type. LastPage = (Context1)Context.Handler; // Display the Value property. lblValue.Text = LastPage.Value; } } private void butBack_Click(object sender, System.EventArgs e) { // Transfer back to the
preceding
page. Server.Transfer("Context1.aspx"); } }
You can transfer complex types from one Web form to another in this way, but remember that the Context.Handler object reflects only the immediately previous Web form ”on postback events, it will reflect the currently displayed Web form. Also remember that the Transfer method does not notify the user s browser that the page address has changed. If the user clicks Refresh on his or her browser, the user receives a warning that the page can t be refreshed without resending information.
Using Query Strings
Query strings allow you to send additional information along with an address. In HTML, query strings appear after a question mark in a hyperlink, as shown here:
<A HREF= "WebForm1.aspx?UName=Wombat">Query string sample.</ A>
To send a query string in code, add it to the address of a Redirect method. The following Click event procedure is equivalent to the preceding HTML:
Visual Basic .NET
Private Sub butSend_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click ' Redisplay this page with a QueryString. Response.Redirect(Request.FilePath & "?UName=Wombat") End Sub
Visual C#
private void butSend_Click(object sender, System.EventArgs e) { // Redisplay this page with a QueryString Response.Redirect(Request.FilePath + "?UName=Wombat"); }
To retrieve a query string in code, use the QueryString method of the Request object. The following code displays the UName item from the query string created in the preceding examples:
Visual Basic .NET
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Check for QueryString If Not IsNothing(Request.QueryString("UName")) Then ' Display message. lblQstring.Text = "QueryString UName=" ' Display QueryString lblQstring.Text += Request.QueryString("UName") End If End Sub
Visual C#
private void Page_Load(object sender, System.EventArgs e) { // Check for QueryString if (Request.QueryString["UName"] != null) { // Display message. lblQstring.Text = "QueryString UName="; // Display QueryString lblQstring.Text += Request.QueryString["UName"]; } }
Using Cookies
Use cookies to store small amounts of information on the client s machine. Web sites often use cookies to store user preferences or other information that is client-specific. Because cookies can be
The following code checks whether a browser allows cookies and then saves user preferences if it does:
Visual Basic .NET
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Run the first time this page is displayed. If Not IsPostBack Then ' If the browser supports cookies If Request.Browser.Cookies Then ' Create a cookie. Dim cookUPrefs As New HttpCookie("UPrefs") cookUPrefs.Value = "English" ' Add the cookie. Response.Cookies.Add(cookUPrefs) End If End If End Sub
Visual C#
private void Page_Load(object sender, System.EventArgs e) { // Run the first time this page is displayed. if(!IsPostBack) // If the browser supports cookies. if(Request.Browser.Cookies) { // Create a cookie. HttpCookie cookUPrefs = new HttpCookie("UPrefs"); cookUPrefs.Value = "English"; // Add the cookie. Response.Cookies.Add(cookUPrefs); } }
The following code checks for a cookie and then gets the cookie if it is available:
Visual Basic .NET
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Run first time page is displayed. If Not IsPostBack Then ' Check if Browser supports cookies. If Request.Browser.Cookies Then ' Check if the UPrefs cookie exists. If Not IsNothing(Request.Cookies("UPrefs")) Then ' Save the value of the cookie. Session("Lang") = Request.Cookies("UPrefs").Value End If End If End If End Sub
Visual C#
private void Page_Load(object sender, System.EventArgs e) { // Run the first time this page is displayed. if(!IsPostBack) // If the browser supports cookies. if(Request.Browser.Cookies) // Check if the UPrefs cookie exists if(Request.Cookies["UPrefs"] != null) // Save the value of the cookie. Session["Lang"] = Request.Cookies["UPrefs"]. Value; }
Using ViewState
Use the ViewState property to save data in a hidden field on a page. Because ViewState stores data on the page, it is limited to items that can be serialized. If you want to store more complex items in ViewState , you must convert the items to and from a string.
For example, the following code adds text from a text box to
Visual Basic .NET
Private Sub butAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles butAdd.Click ' Add text to ViewState ViewState.Add(ViewState.Count, txtValue.Text) End Sub ' This executes just before the page is displayed, ' so it exhibits the affects of the button clicks. Private Sub Page_Prerender(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.PreRender ' Create a new row object. Dim rowNew As New TableRow ' Add row to the table. tblViewState.Rows.Add(rowNew) ' Variable used to enumerate ViewState collection. Dim Item As StateItem ' For each item in the ViewState For Each Item In ViewState.Values() ' Create a new table cell Dim celNew As New TableCell ' Set cell text. celNew.Text = Item.Value ' Addcell to row. rowNew.Cells.Add(celNew) ' Create a new row every four cells. If rowNew.Cells.Count > 3 Then rowNew = New TableRow tblViewState.Rows.Add(rowNew) End If Next End Sub
Visual C#
// This executes just before the page is displayed, // so it exhibits the affects of the button clicks. private void Page_PreRender(object sender, EventArgs e) { // Create a new row object. TableRow rowNew = new TableRow(); // Add row to the table tblViewState.Rows.Add(rowNew); // For each item in the ViewState foreach (StateItem Item in ViewState.Values) { // Create a new table cell TableCell celNew = new TableCell(); // Set cell text. celNew.Text = Item.Value.ToString(); // Add cell to row. rowNew.Cells.Add(celNew); // Create a new row every four cells. if (rowNew.Cells.Count > 3) { rowNew = new TableRow(); tblViewState.Rows.Add(rowNew); } } }
ASP.NET hashes the hidden data stored on the page so that it is not intelligible to users. If you add a few items to the table using the preceding code and then choose View Source from the browser, the HTML for the hidden field looks something like this:
</HEAD> <body MS_POSITIONING="GridLayout"> <form name="Form1" method="post" action="WebForm1.aspx" id=" Form1"> <input type="hidden"name ="__VIEWSTATE" value="dDwtMTMwNzIzM zU0Mzt0PHA8bDwwOzE7MjszOzQ7PjtsPFxlO1RoaXMgaXMgc29tZSB0ZXh 0O1RoaXMgaXMgc29tZSB0ZXh0O1RoaXMgaXMgc29tZSB0ZXh0O1RoaXMgaXM gc29tZSB0ZXh0Oz4+Ozs+Oz4=" />
This hashing
Using Application and Session States
Use the Application and Session states to store data that you want to keep for the lifetime of an application or for the lifetime of a session. You can store any type of data in the Application or Session state, including objects. However, you should consider the following issues before using the Application and Session states:
Application and Session state variables are created on the fly, without variable name or type checking. You should limit your access points to these variables.
Maintaining Session state affects performance. Session state can be turned off at the application and page levels.
Application state variables are available throughout the current process, but not across processes. If an application is scaled to run on multiple servers or on multiple processors within a server, each process has its own Application state.
The Web application s boundaries determine the scope of the Application state.
Structuring Access to State Variables
Application and Session state variables are powerful and therefore scary things. It is easy to introduce some old-style Basic errors in your code if you use these variables in an unstructured manner. For instance, the following code references two different Application state variables:
Visual Basic .NET
Application("Uname") = "Wombat" Response.Write(Application("Unamme"))
Visual C#
Application["Uname"] = "Wombat"; Response.Write(Application["Unamme"]);
The first line creates a variable and stores some text in it. The second line retrieves a new, empty variable and displays nothing, simply because the variable name is
To ameliorate this problem, structure your access to
Application
and
Session
state variables. The
The following code
Visual Basic .NET
Public Class AppSessState Inherits System.Web.UI.Page ' Variable for controlling state access Dim strAppState, strSessState As String Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Get Application and session variables here. ' Check if they exist. If Not IsNothing(Application("AppState")) Then _ strAppState = Application("AppState") If Not IsNothing(Session("SessState")) Then _ strSessState = Session("SessState") End Sub Private Sub butApp_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles butApp.Click strAppState = txtValue.Text End Sub Private Sub butSess_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles butSess.Click strSessState = txtValue.Text End Sub Private Sub Page_PreRender(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.PreRender ' Display values. lblValue.Text = "Application state is: " lblValue.Text += strAppState lblValue.Text += " Session state is: " lblValue.Text += strSessState End Sub Private Sub Page_Unload(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Unload ' Store values before unloading page. Application("AppState") = strAppState Session("SessState") = strSessState End Sub End Class
Visual C#
public class AppSessState : System.Web.UI.Page { // Variable for controlling state access string strAppState = "", strSessState = ""; private void Page_Load(object sender, System.EventArgs e) { // Get Application and session variables here. // Check if they exist. if (Application["AppState"] != null) strAppState = Application["AppState"].ToString(); if (Session["SessState"] != null) strSessState = Session["SessState"].ToString(); } private void butApp_Click(object sender, System.EventArgs e) { strAppState = txtValue.Text; } private void butSess_Click(object sender, System.EventArgs e) { strSessState = txtValue.Text; } private void AppSessState_PreRender(object sender, EventArgs e) { // Display values. lblValue.Text = "Application state is: "; lblValue.Text += strAppState; lblValue.Text += " Session state is: "; lblValue.Text += strSessState; } private void AppSessState_Unload(object sender, EventArgs e) { // Store values before unloading page. Application["AppState"] = strAppState; Session["SessState"] = strSessState; } }
IMPORTANT
In Visual C#, be sure to test whether a state variable is
null
before invoking any of its
Turning Off Session State
ASP.NET maintains
Session
state for each page in your application by default. If a page does not require state information at the session level, you can
To turn Session state off for a Web form:
From the Web Form Properties window, set EnableSessionState to False .
To turn Session state off for an entire application:
In the Web.config file, set the
<
<sessionstate mode="False"/>