Lesson 3: Maintaining State Information

Lesson 3: Maintaining State Information

In this lesson, you ll learn how to retain data on a Web form between requests. ASP.NET provides different mechanisms for saving form data, depending on the nature and scope of the information.

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 variables in Application and Session state

  • 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 destroyed each time a client browser makes a request. Because of this characteristic, variables declared within a Web form do not retain their value after a page is displayed. To solve this problem, ASP.NET provides the following ways to retain variables between requests:

  • Context.Handler object

    Use this object to retrieve public members of one Web form s class from a subsequently displayed Web form.

  • Query strings

    Use these strings to pass information between requests and responses as part of the Web address. Query strings are visible to the user, so they should not contain secure information such as passwords.

  • Cookies

    Use cookies to store small amounts of information on a client. Clients might refuse cookies, so your code has to anticipate that possibility.

  • View state

    ASP.NET stores items added to a page s ViewState property as hidden fields on the page.

  • Session state

    Use Session state variables to store items that you want keep local to the current session (single user).

  • Application state

    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 subsequent Web form is displayed.

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 the next 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 accesses the Context1 Value property, as shown here:

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

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 refused, it is important to check whether the browser allows them before you try to create them.

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 cells in a table on the page. Because you can t store objects directly in ViewState, you must store the strings in the butAdd_Click procedure and then create the table row controls from the strings, as shown in the Page_PreRender procedure.

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 ' Add cell 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" > <input type="hidden" name="__VIEWSTATE" value="dDwtMTMwNzIzM zU0Mzt0PHA8bDwwOzE7MjszOzQ7PjtsPFxlO1RoaXMgaXMgc29tZSB0ZXh 0O1RoaXMgaXMgc29tZSB0ZXh0O1RoaXMgaXMgc29tZSB0ZXh0O1RoaXMgaXM gc29tZSB0ZXh0Oz4+Ozs+Oz4=" />

This hashing prevents malicious users from manipulating ViewState data between requests to corrupt data on the server and also makes the ViewState information from one Web form unreadable from other Web forms.

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 misspelled. The problem is obvious here, but if it occurred deep in a decision structure, it would be very hard to find.

To ameliorate this problem, structure your access to Application and Session state variables. The easiest way to do this is to declare a page-level variable for each item you need, retrieve the Application or Session state value in the Page_Load event procedure, and save the page-level variables back to state in the Page_Unload event procedure. You might want to make retrieving and saving state variables from a consistent location part of your coding conventions.

The following code demonstrates structuring access to state variables:

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 methods, such as ToString. Otherwise, you will receive a run-time error if the state variable does not contain a value.

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 turn this off to achieve better performance.

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=> tag to False, as shown here:

    <sessionstate mode="False"/>



MCAD(s)MCSD Self-Paced Training Kit(c) Developing Web Applications With Microsoft Visual Basic. Net and Microsoft V[.  .. ]0-315
MCAD(s)MCSD Self-Paced Training Kit(c) Developing Web Applications With Microsoft Visual Basic. Net and Microsoft V[. .. ]0-315
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 118

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net