Controlling View State in ASP.NET Mobile Web Pages

Microsoft ASP.NET Web pages are capable of maintaining their own state across round trips. When a property is set for a control, and if the property is configured to maintain state across round trips, ASP.NET saves the property value as part of the control's state. To the application, this makes it appear that the page's lifetime spans multiple client requests. This page-level state is known as the page's view state.

On ordinary ASP.NET Web pages, view state is sent by the server as a hidden field in a form as part of the response to the client, and is returned to the server by the client as part of a postback. However, to reduce bandwidth demand when using mobile controls, ASP.NET does not send a page's view state to the client. Instead, view state is saved as part of a user's session on the server. Where there is a view state, ASP.NET sends a hidden field that identifies this page's view state as part of every response to the client, and the hidden field is returned to the server by the client as part of the next postback.

Managing View State History

Because view state for a given page must be kept on the server, if the user clicks the browser's Back button, it is possible for the current state on the server to be out of synchronization with the current page of the browser. For example, suppose the user goes to Page 1, then clicks a button to go to Page 2, then presses the Back button to return to Page 1. The current page on the browser is now Page 1, but the current state on the server is that of Page 2.

To address this issue, ASP.NET mobile Web pages maintain a history of view state information in the user's session. Each identifier sent to the client corresponds to a position in this history. In the previous example, if the user again posts from Page 1, the mobile Web page uses the identifier saved with Page 1 to synchronize view state history.

You can configure the size of this history to fine-tune it for the application. The default size is 6, and can be changed by adding a numeric attribute to a tag in the Web.config file, as shown in the following example:

<configuration>
  <system.web>
    <mobileControls sessionStateHistorySize="10" />
  </system.web>
</configuration>

Managing Expired Sessions

Because view state is saved in the user's session, it is possible for view state to expire if a page is not posted back within the session expiration time. This expiration is unique to mobile Web pages. When the user posts a page for which there is no view state available, the OnViewStateExpire method of the page is called. The default implementation of this method throws an exception indicating that view state has expired. However, if your application is able to restore view state manually after expiration, you can override this method at the page level and choose not to call the base implementation.

Enabling and Disabling View State

The advantage of using the session to manage view state is that it results in a smaller response size. The disadvantage is that inefficient use of session state can lead to poorer performance. If you use controls that contain large amounts of data, you can improve efficiency with techniques such as custom paging or disabling view state. For example, consider a site that displays news stories. Instead of saving article content for each user session, the site can use smarter data access so that only one copy of each article is cached on the server, and session state usage is minimized.

View state is enabled by default. You can configure controls so that view state is disabled by default for all controls in a page or a container control, but can be enabled for specific controls. You can also configure controls so that view state is disabled and cannot be enabled for child controls.

To disable view state by default for a control so that it can be enabled for specific child controls, set the ViewStateMode property of the control to Disabled. To disable view state by default for a whole page, set the ViewStateMode attribute of the @ Page directive to Disabled.

To disable view state for a control and its children so that it cannot be enabled for child controls, set the EnableViewState property of the control to false. To disable view state for an entire page and all its child controls, set the EnableViewState attribute of the @ Page directive to false.

Even when view state is disabled, some mobile controls save required state information across client round trips. An example of such information includes the currently active form on a page. When you turn off view state, the page saves this required information as a hidden form variable that is sent on a round trip to the client.

Managing Cookies and Client State

By default, the session management features of ASP.NET require the server to write a session cookie to a client. The client subsequently submits the cookie on each request during the session, and the server looks up session state information using the cookie information. However, many mobile devices do not support cookies. For session management (including view state), to work correctly on these devices, you must configure the application to use cookieless session management. With this feature enabled, ASP.NET automatically inserts the session key in application URLs.

Some devices do not support cookies. To persist long-term client state, an application can use client-specific information, such as a customer number entered by the user. Because you cannot rely on a client having cookies, your application must take you to an alternate page that can be bookmarked. The following sample shows an example. Users that browse to this URL view a form where they enter their customer IDs. The application then displays an alternate URL, which users can bookmark.

<%@ Page Inherits="System.Web.UI.MobileControls.MobilePage"
    Language="C#"
    EnableViewState="false" %>

<script runat="server" language="c#">
protected void Page_Load(Object sender, EventArgs e)
{
    String customerID = Request.QueryString["cid"];

    if (customerID != null)
    {
        // A customer ID was found. Simulate a lookup by 
        // converting the client ID back to a user.
        int underscore = customerID.IndexOf('_');
        if (underscore != -1)
        {
            // If visiting the first time, prompt the user to bookmark.
            if (Session["FirstTime"] != null)
            {
                Session["FirstTime"] = null;
                WelcomeLabel.Text = String.Format("Welcome, {0}", 
                customerID.Substring(0, underscore));
                ActiveForm = WelcomeForm;
            }
            else
            {
                ReturnLabel.Text = String.Format("Welcome back, {0}", 
                    customerID.Substring(0, underscore));
                ActiveForm = ReturnForm;
            }
        }
    }
}

protected void LoginForm_OnSubmit(Object sender, EventArgs e)
{
    // Generate a customer ID. Normally, you would create
    // a new customer profile.
    String customerID = CustomerName.Text + "_" + 
        System.Guid.NewGuid().ToString();
    String path = AbsoluteFilePath + "?cid=" + 
        Server.UrlEncode(customerID);
    Session["FirstTime"] = true;
    RedirectToMobilePage(path);
}
</script>

<mobile:Form runat="server">
  <mobile:Label runat="server" StyleReference="title">
    Welcome to the site. Please register to continue.
  </mobile:Label>
  <mobile:TextBox runat="server" id="CustomerName" />
  <mobile:Command runat="server" OnClick="LoginForm_OnSubmit" 
    Text="Register" />
</mobile:Form>

<mobile:Form id="WelcomeForm" runat="server">
  <mobile:Label runat="server" id="WelcomeLabel" />
    Please bookmark this page for future access.
</mobile:Form>

<mobile:Form id="ReturnForm" runat="server">
  <mobile:Label runat="server" id="ReturnLabel" />
</mobile:Form>

Optimizing View State for Mobile Applications

For mobile Web pages, the following considerations are important:

  • Saving view state to session state is highly optimized. If there is no view state to save, nothing is stored in the session, and no identifier is sent to the client. However, application developers who want to avoid using session management, or who want pages capable of high throughput, can consider reducing or eliminating the use of view state. In many application cases (such as rendering a page of formatted text), view state is unnecessary and is best turned off.

  • In addition to application view state, a mobile Web page must store other types of state information about the page. This information might include the active form or pagination information about the form. Such information is always sent to the client rather than kept on the server, and is usually generated in an optimized way. For example, if the first form is active, or the first page of a form is being shown, this information is not saved, because these are default states. Such state information is called the private view state. All controls can override the LoadPrivateViewState and SavePrivateViewState methods to read and write private view state.

    Note

    Good security practice demands that if you include sensitive information in session state, you use a connection with HTTPS and SSL/TLS authentication.

See Also

Reference

Page.EnableViewState

Control.EnableViewState

Control.ViewStateMode

Concepts

ASP.NET State Management Overview

ASP.NET View State Overview

Controlling Session State in ASP.NET Mobile Web Pages

Other Resources

Supporting View State