Team LiB
Previous Section Next Section

Client-Side State Management

When it comes to state management, there are two basic choices to make: Should you maintain the state by using server-side techniques or should you maintain the state on the client? In the following sections, you will learn how to maintain state using some client-side techniques such as ViewState, hidden form fields, cookies, and query strings.

Understanding View State

A very simple way of managing the view state of an ASP.NET server control is through the use of the Control.ViewState property.

TIP

The Control.ViewState property returns a System.Web.UI.StateBag object. A StateBag object is the primary storage method employed by HTML and server controls. It stores this information as name/value pairs and implements a dictionary to do so. Therefore you can perform operations, such as adding and removing of objects, on the StateBag object in the same manner as you would on the Dictionary object itself. The ViewState property is persisted by the ASP.NET Framework as strings, and is passed to the client by using a hidden form variable.


To store a value in the ViewState property, simply access the StateBag as you would a Dictionary object:

someControl.ViewState["Value Name"] = someValue;

A value can be written to the ViewState anytime after a page has been initialized from persistent settings, but you should avoid writing to it while the control is rendering. Reading from the ViewState is simply the opposite of writing to it:

someValue = someControl.ViewState["Value Name"];

You can read from the ViewState at any time. If you want your data to be displayed on a form, you should read it from the ViewState in the Form.OnPreRender event. The ViewStateExample project in Listings 23.1 and 23.2 illustrates how to store and retrieve values from the ViewState property.

Listing 23.1. ViewStateExampleForm.aspx
<%@ Page language="c#"
  Codebehind="ViewStateExampleForm.aspx.cs"
  AutoEventWireup="false" Inherits="ViewStateExample.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
    <meta content="C#" name="CODE_LANGUAGE">
    <meta content="JavaScript" name="vs_defaultClientScript">
    <meta content="http://schemas.microsoft.com/intellisense/ie5" 
     name="vs_targetSchema">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:textbox id="userName"
         style="Z-INDEX: 101; LEFT: 73px; POSITION: absolute; TOP: 115px" runat="server">
      </asp:textbox>
      <asp:label id="userLabel"
        style="Z-INDEX: 102; LEFT: 73px; POSITION: absolute; TOP: 82px"
        runat="server">User Name</asp:label>
      <asp:label
        id="userGreeting"
        style="Z-INDEX: 103; LEFT: 73px; POSITION: absolute; TOP: 39px"
        runat="server">
      Please enter your user name below and press the submit button.</asp:label>
      <asp:button id="submitButton"
        style="Z-INDEX: 104; LEFT: 73px; POSITION: absolute; TOP: 166px"
        runat="server" Text="Submit"></asp:button></form>
  </body>
</HTML>

Listing 23.2. ViewStateExampleForm.aspx.cs
   using System;
   using System.Collections;
   using System.ComponentModel;
   using System.Data;
   using System.Drawing;
   using System.Web;
   using System.Web.SessionState;
   using System.Web.UI;
   using System.Web.UI.WebControls;
   using System.Web.UI.HtmlControls;

   namespace ViewStateExample
   {
     /// <summary>
     /// Summary description for WebForm1.
     /// </summary>
     public class WebForm1 : System.Web.UI.Page
     {
  protected System.Web.UI.WebControls.TextBox userName;
       protected System.Web.UI.WebControls.Label userLabel;
       protected System.Web.UI.WebControls.Button submitButton;
       protected System.Web.UI.WebControls.Label userGreeting;

       private void Page_Load(object sender, System.EventArgs e)
       {
       }

       #region Web Form Designer generated code
       override protected void OnInit(EventArgs e)
       {
         //
         // CODEGEN: This call is required by the ASP.NET Web Form Designer.
         //
         InitializeComponent();
         base.OnInit(e);
       }

       /// <summary>
       /// Required method for Designer support - do not modify
       /// the contents of this method with the code editor.
       /// </summary>
       private void InitializeComponent()
       {
         this.submitButton.Click += new System.EventHandler(this.Submit_Click);
         this.Load += new System.EventHandler(this.Page_Load);
         this.PreRender += new System.EventHandler(this.WebForm1_PreRender);
       }
       #endregion

       private void WebForm1_PreRender(object sender, System.EventArgs e)
       {
         string userResponse = (string) this.ViewState["User Name"];
         if((null != userResponse) && !userResponse.Equals(string.Empty))
         {
           submitButton.Visible  = false;
           userLabel.Visible     = false;
           userName.Visible      = false;
           userGreeting.Text     = "Thank you " + userResponse + " for entering your name.";
         }
       }

       private void Submit_Click(object sender, System.EventArgs e)
       {
         this.ViewState["User Name"] = userName.Text;
       }
     }
   }

This example uses two label controls and one edit control . Figure 23.1 shows that the first label control is a greeting that invites the user to enter his username.

Figure 23.1. ViewStateExampleForm.aspx in Design view.


When the user enters his username (see Figure 23.2) and submits the form, the application stores the value entered by the user in the ViewState with a named value of User Name. When the form is posted back to the user, the application reads the User Name value from ViewState and populates the greeting label with a personalized thank you to the user for entering his information. This is demonstrated in Figure 23.3.

Figure 23.2. This is the initial screen before entering a username.


Figure 23.3. The same screen after the post back occurs.


Customizing the ViewState

Because the ViewState serializer is optimized for primitive types, it is sometimes desirable to customize the way ViewState persists property data. However, if you customize the way that the ViewState stores these values, you must also customize the way the ViewState retrieves the values. The ASP.NET Framework offers two methods to customize this behavior: Control.SaveViewState and Control.LoadViewState. To customize the way in which ViewState is saved, simply override the SaveViewState method and save the data as described in the following code snippet:

protected override object SaveViewState()
{
  // Save State as an array of objects.  This could also be a class or anything else.
  object baseState = base.SaveViewState();
  string password  = EncryptPassword(passwordText);
  object[] viewStates = new object[2];
  viewStates[0] = baseState;
  viewStates[1] = password;

  return viewStates;
}

Reading the data back is done in a similar way. Simply override the LoadViewState method and read back the data. This is demonstrated by the following code fragment:

protected override void LoadViewState(object savedState)
{
  if(null != savedState)
  {
    // Since the data was saved as an array of objects, we must read it back the same way.
    base.LoadViewState(savedState[0]);
    // Some error checking should be placed here, but is omitted for brevity.
    string password = (string) savedState[1];
    passwordText = DecryptPassword(password);
    ... // Do something here with the passwordText that was decrypted.
  }
}

Using Hidden Form Fields

Using hidden form fields is another easy way to implement client-side state management. ASP.NET enables you to use standard HTML hidden fields to store a single variable in its value property. When a form is submitted to the server, the hidden field is available to you in just the same way as all other fields on that page.

TIP

In order for the variable stored in the hidden field to be available to you, the form must be sent to the server using the submit method. Using a page redirect or the HTTP get command will not enable you to use the variable.


Although the use of hidden fields is an easy way to manage state, it presents something of a security concern. The variable stored in these fields is available to any user who chooses to view the source of the page. Therefore, if you have any data that is privacy-sensitive or if you just don't want anyone to see its value, you should not use this technique to manage your form's state. By modifying the ViewStateExample program listed in the previous section, you will get a better understanding of what it will take to use a hidden variable. First, drop an HtmlInputHidden control on the form and change the ID to userInputState. The design view of the form after this control has been added. Next, switch to the HTML view, as shown in Listing 23.3, and make the new control a server control by adding the runat="server" attribute to the control. This is demonstrated in the following code snippet:

<INPUT style="Z-INDEX: 105; LEFT: 72px; POSITION: absolute; TOP: 248px"
type="hidden" name="userNameState"
runat="server" id="userNameState">

TIP

When you add an HTML control to a form and you need to access the variable in the code-behind page, you must manually add the declaration to the class and make the control a server-side control. You also must use as the variable name the same name that is listed in the ID attribute of the control. If you don't, ASP.NET will not link the control and the variable declaration together and you will receive an Object reference not set to an instance of an object exception when you try to access the variable.


Next, change the submit event to set the value of the hidden variable to the value of the text control:

userNameState.Value = userName.Text;

Finally, change the OnPreRender event to read the value from the hidden field and populate the text control with this value:

string userResponse = (string) userNameState.Value;

If you now run the application, you will see that the sample program runs the same way it did when you ran the ViewStateExample program. The one difference occurs when you view the HTML source of the running page. If you select the menu items View, and then Source from the Internet Explorer menu, the source for the page will appear. You will notice that the value of the hidden variable appears in this listing. This is demonstrated in Listing 23.5. If you don't mind that this variable is visible to anyone who cares to view it, this side effect will not mean much. However, if this is a concern to you, do not use this method.

Listing 23.3. HiddenVariableExample.aspx
<%@ Page language="c#"
   Codebehind="HiddenVariableExample.aspx.cs" AutoEventWireup="false"
   Inherits="HiddenVariableStateExample.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
    <meta content="C#" name="CODE_LANGUAGE">
    <meta content="JavaScript" name="vs_defaultClientScript">
    <meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:textbox id="userName"
       style="Z-INDEX: 101; LEFT: 73px; POSITION: absolute; TOP: 115px"
       runat="server"></asp:textbox>
      <asp:label id="userLabel"
       style="Z-INDEX: 102; LEFT: 73px; POSITION: absolute; TOP: 82px"
       runat="server">User Name</asp:label>
      <asp:label id="userGreeting"
        style="Z-INDEX: 103; LEFT: 73px; POSITION: absolute; TOP: 39px"
        runat="server">Please enter your user name below and press the submit button.
      </asp:label>
      <asp:button id="submitButton"
        style="Z-INDEX: 104; LEFT: 73px; POSITION: absolute; TOP: 166px"
        runat="server" Text="Submit"></asp:button>
      <INPUT style="Z-INDEX: 105; LEFT: 72px; POSITION: absolute; TOP: 248px"
        type="hidden" name="userNameState" runat="server" id="userNameState">
    </form>
  </body>
</HTML>

Listing 23.4. HiddenVariableExample.aspx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace HiddenVariableStateExample
{
  // <summary>
  // Summary description for WebForm1.
  // </summary>
  public class WebForm1 : System.Web.UI.Page
  {
    protected System.Web.UI.HtmlControls.HtmlInputHidden userNameState;
    protected System.Web.UI.WebControls.TextBox userName;
    protected System.Web.UI.WebControls.Label userLabel;
    protected System.Web.UI.WebControls.Label userGreeting;
    protected System.Web.UI.WebControls.Button submitButton;

    private void Page_Load(object sender, System.EventArgs e)
    {
      // Put user code to initialize the page here
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
      //
      // CODEGEN: This call is required by the ASP.NET Web Form Designer.
      //
      InitializeComponent();
      base.OnInit(e);
    }

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.submitButton.Click += new System.EventHandler(this.submitButton_Click);
      this.Load += new System.EventHandler(this.Page_Load);
      this.PreRender += new System.EventHandler(this.WebForm1_PreRender);
    }
    #endregion

    private void submitButton_Click(object sender, System.EventArgs e)
    {
      userNameState.Value = userName.Text;
    }

    private void WebForm1_PreRender(object sender, System.EventArgs e)
    {
      string userResponse = (string) userNameState.Value;
      if((null != userResponse) && !userResponse.Equals(string.Empty))
      {
        submitButton.Visible  = false;
        userLabel.Visible     = false;
        userName.Visible      = false;
        userGreeting.Text     = "Thank you " + userResponse + " for entering your name.";
      }
    }
  }
}

Listing 23.5. Source View
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
    <meta content="C#" name="CODE_LANGUAGE">
    <meta content="JavaScript" name="vs_defaultClientScript">
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form name="Form1" method="post" action="HiddenVariableExample.aspx" id="Form1">
    <input type="hidden" name="__VIEWSTATE"
 value="dDwzNDY2NjIxNTU7dDw7bDxpPDE+Oz47bDx0PDtsPGk8MT47aTwzPjtpPDU+O2k8Nz47PjtsPHQ8cDxwPGw8VGV4dDtWaXNpYmxlOz47bDxMb25ueTtvPGY+Oz4+Oz47Oz47dDxwPHA8bDxWaXNpYmxlOz47bDxvPGY+Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxUaGFuayB5b3UgTG9ubnkgZm9yIGVudGVyaW5nIHlvdXIgbmFtZS47Pj47Pjs7Pjt0PHA8cDxsPFZpc2libGU7PjtsPG88Zj47Pj47Pjs7Pjs+Pjs+Pjs+3ixLXNlHEiVE3uZwiE/gsLivikQ="
 />
      <span id="userGreeting" style="Z-INDEX: 103; LEFT: 73px; POSITION: absolute; TOP:
 39px">Thank you Lonny for entering your name.</span>
      <input name="userNameState" id="userNameState" type="hidden" style="Z-INDEX: 105;
 LEFT: 72px; POSITION: absolute; TOP: 248px" value="Hidden Variable Value Is Shown Here" />
    </form>
  </body>
</HTML>

Explaining Cookies

Although a cookie is nothing more then a text file that can store user actions, values, and preferences, it is both a popular and convenient way of storing state information on the client side. Some of the benefits of using cookies are that they are lightweight, they have a configurable expiration, and they don't require any server resources. Unfortunately, along with these benefits come some pretty serious disadvantages. Among the disadvantages of cookies are that they can be easily manipulated by malicious users, they can be disabled by the user, and they are limited in size.

Although some newer browsers support a maximum cookie size of 8192 bytes, most older browsers support a maximum size of only 4192 bytes. If your goal is to simply store some user preferences or some identifying information for the user, this should not be a problem. However, if your goal is to store information that is of a sensitive nature, you might want to think about a different way of managing state. The values that you store in a cookie can be viewed by a user by simply loading the cookie file in Windows Notepad. In addition, a user could modify this information and potentially expose a security flaw in your application.

Cookies are generally used to store user preferences, and possibly an identity key that allows the system to automatically identify the user. In addition, cookies generally have an expiration date. This can be set by using the HttpCookie.Expires property. When the cookie expires, the system deletes it.

The example in Listings 23.6 and 23.7 takes the code example introduced in the ViewState section and modifies it slightly to store information in a cookie. This example contains one page that, upon initialization or postback, checks for the existence of a cookie. If the cookie exists, the system loads the "user" value and displays a message to the user welcoming her back to the website. If a cookie does not exist, the system prompts the user to enter her username. After the user has entered her username and submitted the form, the system rechecks for the existence of the cookie. If the cookie exists, the system welcomes the user.

Listing 23.6. CookieExample.aspx Design View
<%@ Page language="c#" Codebehind="CookieExample.aspx.cs"
  AutoEventWireup="false" Inherits="CookieExample.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
    <meta content="C#" name="CODE_LANGUAGE">
    <meta content="JavaScript" name="vs_defaultClientScript">
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:textbox id="userName"
       style="Z-INDEX: 101; LEFT: 73px; POSITION: absolute; TOP: 115px"
       runat="server"></asp:textbox>
      <asp:label id="userLabel"
        style="Z-INDEX: 102; LEFT: 73px; POSITION: absolute; TOP: 82px"
        runat="server">User Name</asp:label>
      <asp:label id="userGreeting"
        style="Z-INDEX: 103; LEFT: 73px; POSITION: absolute; TOP: 39px"
        runat="server">Please enter your user name below and press the submit button.
      </asp:label>
      <asp:button id="submitButton"
        style="Z-INDEX: 104; LEFT: 73px; POSITION: absolute; TOP: 166px"
        runat="server" Text="Submit"></asp:button>
    </form>
  </body>
</HTML>

Listing 23.7. CookieExample.aspx.cs Source View
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace CookieExample
{
  /// <summary>
  /// Summary description for CookieExample.
  /// </summary>
  public class WebForm1 : System.Web.UI.Page
  {
    protected System.Web.UI.WebControls.Label userGreeting;
    protected System.Web.UI.WebControls.Button submitButton;
    protected System.Web.UI.WebControls.TextBox userName;
    protected System.Web.UI.WebControls.Label userLabel;

    private void Page_Load(object sender, System.EventArgs e)
    {
      // Put user code to initialize the page here
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
      //
      // CODEGEN: This call is required by the ASP.NET Web Form Designer.
      //
      InitializeComponent();
      base.OnInit(e);
    }
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.submitButton.Click += new System.EventHandler(this.submitButton_Click);
      this.Load += new System.EventHandler(this.Page_Load);
      this.PreRender += new System.EventHandler(this.WebForm1_PreRender);
    }
    #endregion

    private void submitButton_Click(object sender, System.EventArgs e)
    {
      HttpCookie userCookie = new HttpCookie("User Name");
      DateTime now          = DateTime.Now;

      userCookie.Value      = userName.Text;
      userCookie.Expires    = now.AddHours(5);

      Response.Cookies.Add(userCookie);
    }

    private void WebForm1_PreRender(object sender, System.EventArgs e)
    {
      HttpCookie userCookie = Request.Cookies.Get("User Name");

      if(null != userCookie)
      {
        string userResponse = (string) userCookie.Value;

        if((null != userResponse) && !userResponse.Equals(string.Empty))
        {
          submitButton.Visible  = false;
          userLabel.Visible     = false;
          userName.Visible      = false;
          userGreeting.Text     =
"Thank you " + userResponse + " for entering your name.";
        }
      }
    }
  }
}

TIP

The contents of a cookie are easily viewed and manipulated by a user. The contents of the cookie that was created by the CookieExample program are listed here:

User Name<CR>Lonny Kruger<CR>localhost/<CR>1024
<CR>1478352000<CR>29641125<CR>1876798432<CR>29641083<CR>*

As you can see, the username entered in the file is Lonny Kruger. If you change this name to something else and run the program again, you will see a welcome message that welcomes the user with the modified name.


Understanding Query Strings

Query strings are by far the easiest form of state management to understand. Using query strings to manage state has the following advantages: There are no server resources used, this approach is easy to implement, and just about all browsers support this method of state management. There are, however a few minor disadvantages. Some of these disadvantages are that most browsers support a maximum of only 255 characters in a query string and, like cookies, query strings are easily manipulated.

To use the query string method, simply append a question mark (?) to the URL, followed by the name and value pair that you want to pass to the next form. If you need to pass multiple values, simply separate the multiple name/value pairs by using an ampersand (&) character.

Passing a single value:

http://localhost/QueryStringExample/QueryStringExample.aspx?userName=Lonny

Passing multiple values:

http://localhost/QueryStringExample/QueryStringExample.aspx?firstName=Lonny&lastName=Kruger

The following example, Listing 23.8, again modifies the original ViewState example and accomplishes the same task by using query strings.

Listing 23.8. QueryStringExample.aspx HTML View
<%@ Page language="c#" Codebehind="QueryStringExample.aspx.cs"
  AutoEventWireup="false" Inherits="QueryStringExample.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
    <meta content="C#" name="CODE_LANGUAGE">
    <meta content="JavaScript" name="vs_defaultClientScript">
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:textbox id="userName"
       style="Z-INDEX: 101; LEFT: 73px; POSITION: absolute; TOP: 115px"
       runat="server"></asp:textbox>
      <asp:label
        id="userLabel" style="Z-INDEX: 102; LEFT: 73px; POSITION: absolute; TOP: 82px"
        runat="server">User Name</asp:label>
      <asp:label
        id="userGreeting" style="Z-INDEX: 103; LEFT: 73px; POSITION: absolute; TOP: 39px"
        runat="server">Please enter your user name below and press the submit button.</asp
:label>
      <asp:button id="submitButton"
        style="Z-INDEX: 104; LEFT: 73px; POSITION: absolute; TOP: 166px"
        runat="server" Text="Submit"></asp:button>
      <INPUT
        style="Z-INDEX: 105; LEFT: 72px; POSITION: absolute; TOP: 248px"
        type="hidden" name="userNameState"
         runat="server" id="userNameState">
    </form>
  </body>
</HTML>

Listing 23.9. QueryStringExample.aspx.cs Source View
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace QueryStringExample
{
  /// <summary>
  /// Summary description for WebForm1.
  /// </summary>
  public class WebForm1 : System.Web.UI.Page
  {
    protected System.Web.UI.HtmlControls.HtmlInputHidden userNameState;
    protected System.Web.UI.WebControls.TextBox userName;
    protected System.Web.UI.WebControls.Label userLabel;
    protected System.Web.UI.WebControls.Label userGreeting;
    protected System.Web.UI.WebControls.Button submitButton;

    private void Page_Load(object sender, System.EventArgs e)
    {
        // Put user code to initialize the page here
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
        //
        // CODEGEN: This call is required by the ASP.NET Web Form Designer.
        //
        InitializeComponent();
        base.OnInit(e);
    }

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.submitButton.Click += new System.EventHandler(this.submitButton_Click);
      this.Load += new System.EventHandler(this.Page_Load);
      this.PreRender += new System.EventHandler(this.WebForm1_PreRender);
    }
    #endregion

    private void submitButton_Click(object sender, System.EventArgs e)
    {
      Response.Redirect(
         "http://localhost/QueryStringExample/QueryStringExample.aspx?userName=" +
         userName.Text);
      //userNameState.Value = userName.Text;
    }

    private void WebForm1_PreRender(object sender, System.EventArgs e)
    {
      string userResponse = (string) Request.QueryString["userName"];
      if((null != userResponse) && !userResponse.Equals(string.Empty))
      {
        submitButton.Visible  = false;
        userLabel.Visible     = false;
        userName.Visible      = false;
        userGreeting.Text     = "Thank you " + userResponse + " for entering your name.";
      }
    }
  }
}

Passing Server Control Values Between Forms

One reason for using state management is to pass data between forms. ASP.NET offers a few different ways to accomplish this feat: ViewState, query strings, and SessionState. Although these are good ways of accomplishing the task, there is a better way of achieving the same result.

Instances of Web Forms exist for only a short period of time. They usually exist only long enough to perform page processing. As such, it is difficult to pass data between the pages. Fortunately, ASP.NET enables you to transfer control to another form. When you transfer control from one Web Form to another, you gain access to the Web Form that transferred control and, as such, you also gain access to the properties exposed by this form.

The example in Listings 23.1023.13 demonstrates how to transfer control from one form to another. This sample program again slightly modifies the example introduced in the ViewState section earlier in the chapter.

Listing 23.10. FirstForm.aspx HTML View
<%@ Page language="c#"
  Codebehind="FirstForm.aspx.cs"
  AutoEventWireup="false" Inherits="PassingServerControlValuesExample.FirstForm" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
    <meta content="C#" name="CODE_LANGUAGE">
    <meta content="JavaScript" name="vs_defaultClientScript">
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:textbox
        id="userName" style="Z-INDEX: 101; LEFT: 73px; POSITION: absolute; TOP: 115px"
        runat="server"></asp:textbox>
      <asp:label
        id="userLabel" style="Z-INDEX: 102; LEFT: 73px; POSITION: absolute; TOP: 82px"
        runat="server">User Name</asp:label>
      <asp:label id="userGreeting"
        style="Z-INDEX: 103; LEFT: 73px; POSITION: absolute; TOP: 39px"
        runat="server">
        Please enter your user name below and press the submit button.</asp:label>
      <asp:button
        id="submitButton" style="Z-INDEX: 104; LEFT: 73px; POSITION: absolute; TOP: 166px"
        runat="server" Text="Submit"></asp:button>
    </form>
  </body>
</HTML>

Listing 23.11. FirstForm.aspx.cs Code View
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace PassingServerControlValuesExample
{
  /// <summary>
  /// Summary description for WebForm1.
  /// </summary>
  public class FirstForm : System.Web.UI.Page
  {
    protected System.Web.UI.WebControls.TextBox userName;
    protected System.Web.UI.WebControls.Label userLabel;
    protected System.Web.UI.WebControls.Label userGreeting;
    protected System.Web.UI.WebControls.Button submitButton;

    private void Page_Load(object sender, System.EventArgs e)
    {
        // Put user code to initialize the page here
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
        //
        // CODEGEN: This call is required by the ASP.NET Web Form Designer.
        //
        InitializeComponent();
        base.OnInit(e);
    }

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.submitButton.Click += new System.EventHandler(this.submitButton_Click);
      this.Load += new System.EventHandler(this.Page_Load);

    }
    #endregion

    private void submitButton_Click(object sender, System.EventArgs e)
    {
      Server.Transfer("SecondForm.aspx");
    }

    public string UserName
    {
      get
      {
        return userName.Text;
      }
    }
  }
}

TIP

Although Server.Transfer might seem to solve a lot of your problems, it can be used only in a single-server situation.


Listing 23.12. SecondForm.aspx HTML View
<%@ Page language="c#"
    Codebehind="SecondForm.aspx.cs" AutoEventWireup="false"
    Inherits="PassingServerControlValuesExample.SecondForm" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>SecondFom</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name="vs_defaultClientScript" content="JavaScript">
    <meta name="vs_targetSchema"
      content="http://schemas.microsoft.com/intellisense/ie5">
  </HEAD>
  <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
      <asp:label id="userGreeting"
        style="Z-INDEX: 103; LEFT: 80px; POSITION: absolute; TOP: 40px"
        runat="server">
        Please enter your user name below and press the submit button.</asp:label>
    </form>
  </body>
</HTML>

Listing 23.13. SecondForm.aspx.cs Code View
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace PassingServerControlValuesExample
{
  /// <summary>
  /// Summary description for SecondForm.
  /// </summary>
  public class SecondForm : System.Web.UI.Page
  {
    protected System.Web.UI.WebControls.Label userGreeting;
    public FirstForm firstForm;

    private void Page_Load(object sender, System.EventArgs e)
    {
      if(!IsPostBack)
      {
        firstForm = (FirstForm) Context.Handler;
        userGreeting.Text     =
          "Thank you " + firstForm.UserName + " for entering your name.";
      }
    }

    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
        //
        // CODEGEN: This call is required by the ASP.NET Web Form Designer.
        //
        InitializeComponent();
        base.OnInit(e);
    }
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.Load += new System.EventHandler(this.Page_Load);
    }
    #endregion
  }
}

    Team LiB
    Previous Section Next Section