Design and Implementation Guidelines for Web Clients

Retired Content
This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

 

patterns & practices Developer Center

Microsoft Corporation

November 2003

Applies to:
   Microsoft .NET Framework
   ASP.NET

Summary: This chapter describes the types of state used in the presentation layer and offers guidance about how to manage state in applications written for the Web. Correct state management is critical to the scalability and availability of Web applications.

Contents

In This Chapter

Understanding Presentation Layer State

Planning State Management for Web Applications

Serializing State

Caching State

Summary

In This Chapter

This chapter describes how to manage state in the presentation layer in Web applications. The chapter includes the following sections:

  • Understanding Presentation Layer State
  • Planning State Management for Web Applications

State management is an important aspect of many applications. In the presentation layer, you frequently have to store information about the state of the application or keep track of user state information. Some examples of state include:

  • The identity of the current user
  • The contents of a shopping cart
  • The current step in a navigation flow of the application
  • A database connection string

When designing your application, you have to make decisions about how to handle state management, including what to store, where to store it, and how long information will be kept.

The Microsoft .NET Framework provides access to a rich set of state management mechanisms for both Windows-based and Web applications. This chapter describes state management mechanisms for Web applications.

Before looking at the individual mechanisms for state management, make sure that you understand the nature of application state to select the most appropriate mechanism.

Understanding Presentation Layer State

Three characteristics of state determine the state management mechanism most appropriate to your requirements. These three characteristics are:

  • State lifetime
  • State scope
  • State type

The next sections describe each of these characteristics.

Determining State Lifetime

The lifetime of state refers to the period when that state is valid. Table 5.1 lists the common lifetime periods you use in your presentation layer.

Table 5.1: Common Lifetimes for Application State

State lifetime Description Example
Permanent Data that is always valid Information stored in a database
Process Data that is valid only within the scope of a particular process The process a user must go through to add an item to a shopping cart in an online store
Session Data that is valid only within the scope of a single session for a single user The contents of a user's shopping cart
Message Data that is valid only within the scope of a single message or data exchange The checkout request made by a user
Time span Data that is valid only until a particular date and time A coupon code that expires in two weeks

During the design process you must identify the most appropriate lifetime for your user interface state.

Determining State Scope

The scope of state defines the accessibility of an application's state. Scope is additionally divided as follows:

  • Physical scope
  • Logical scope

The following sections describe the various kinds of physical and logical scope available.

Determining Physical Scope

Physical scope defines the physical locations that state can be accessed from. Table 5.2 lists common physical scopes for application state.

Table 5.2: Common Physical Scopes for Application State

State Physical Scope Description Example
Organization State is accessible to all applications in an organization Organizational information stored in Microsoft Active Directory® directory service
Farm State is accessible to all computers in an application farm Information stored in a shared database associated with the farm
Computer State is accessible to all applications running on a computer Information stored on the file system or a local database (with no restricting permissions)
Process State is accessible to multiple application domains running in the same process Identity of the process
Application Domain State is accessible only to code running in a single application domain Objects stored in the application domain's CurrentDomain property

When designing your presentation layer, consider the affect of the various options for physical state storage locations, and select the most appropriate one for your application.

Determining Logical Scope

Logical scope defines the logical locations where state can be accessed. Table 5.3 lists common logical scopes for application state.

Table 5.3: Common Logical Scopes for Application State

State Logical Scope Description Example
Application State is accessible only in a certain application Application-specific information stored in a database
Business Process State is accessible only to elements of a single business process A purchase order being built by a business process
Role State is accessible only to a particular role or group of users Payroll information
User State is accessible only to a particular user The contents of a specific user's shopping cart
View State is only relevant to a particular form, page, or control The contents of a data grid

Selecting the correct logical scope for your presentation layer state is important because it has a significant affect on security and performance.

Determining State Type

The purpose, content, and quantity of state data are important factors when determining the state management mechanism to implement. Table 5.4 lists the characteristics of state that have the most effect on your choice of state management mechanism.

Table 5.4: Common Types of Application State

State Type Description Example
Secret / Sensitive Information that is intended for a specific audience Bank account transactions; private key used for encryption
Insensitive Information that is not restricted in who, what, or both, that can see it Public key used for encryption; hit count for a Web site
Object Information that is stored in an object such as a DataSet or a Hashtable The working set for a user performing an administration task offline
Scalar Information that is stored in a single value The number of times a user has executed an application
Large State that takes up a large amount of storage space The daily order report for a large e-commerce Web site
Small State that takes up a small amount of storage space The user ID of the user logged in to the application
Durable Information that must be stored in a permanent medium to survive, for example, computer reboots A submitted customer order
Transient Information that is not required to be stored in a permanent medium The current page that a user is on in a Web application

You must be familiar with the types of state your presentation layer must manage. Most applications use a combination of the state types listed in Table 5.4.

Planning State Management for Web Applications

Applications based on Web Forms are inherently stateless, but it is frequently necessary for an application to keep track of state information. ASP.NET simplifies state management by providing access to a variety of client-side and server-side state management mechanisms:

  • Client-side state management mechanisms–Cookies, hidden form fields, query strings, and the ViewState property.
  • Server-side state management mechanisms–Session state, application state, and a database.

Table 5.5 lists these mechanisms and provides an indication of the state lifetime, scope, and type that the particular mechanism is most appropriate for.

Table 5.5: State Management Mechanisms for Web Applications

Mechanism Lifetime Physical Scope Logical Scope Type
Session object: In-process Session Process Application,
User
Any
Session object: State server Session Organization Application,
User
Any
Session object: SQL Server Session Organization Application,
User
Any
Cookies Permanent
Session
Time span
Web farm Application, User Small, non-essential, insensitive
Hidden form fields Message Web farm Application, User, View Small, non-essential, insensitive
Query strings (URL fields) Message Web farm Application Small, non-essential, insensitive
ViewState Message Web farm View Small, non-essential, insensitive
Application object Process Process Application Any
Database Application-controlled Datacenter Application Any

The following sections describe each of the state storage mechanisms listed in Table 5.5. Each section provides:

  • An overview of the mechanism
  • Guidance on when to use the mechanism, and points to consider before deciding to use the mechanism
  • Sample code and configuration settings, to show how to use the mechanism

When planning your Web application, use the following guidance to identify and implement the most appropriate state storage mechanism for your presentation layer.

Note   If you want to encapsulate the choice of state storage mechanism in an ASP.NET Web application, you can use the Microsoft User Interface Process Application Block to manage state storage. You can configure the block to use the Session object or SQL Server to store state information.

For more information about using this block to manage state storage, see the "To create a controller class" procedure in Chapter 2 of this guide.

Storing State in the Session Object

By default, whenever a new client connects to an ASP.NET application, ASP.NET creates a cookie on the client containing a unique session identifier (ID). With each subsequent request, the client passes the cookie to the application. This allows the application to maintain context across a series of stateless Web requests. If the client or application is configured to disallow cookies, ASP.NET encodes the session ID as part of the URL the client uses when making requests to the application.

The Session object provides a state store that is unique for each session. Internally, ASP.NET manages Session objects for each active client session and makes the appropriate Session object available in your application through the Session property of the System.Web.UI.Page class, where all Web Forms pages inherit from.

The benefits of using the Session object include:

  • The ASP.NET runtime manages the mapping of the session ID to session data.
  • State data is easily accessible through the page-level Session property.
  • You can configure a timeout after which ASP.NET terminates an inactive Session and disposes of the state for that session.
  • State is not transmitted to clients, so this mechanism is efficient for network bandwidth purposes and more secure than mechanisms such as cookies and hidden form fields.
  • Session management events can be raised and used by your application.
  • Data placed in session-state variables can survive Internet Information Services (IIS) restarts and worker-process restarts without losing session data, because the data is stored in another process space.
  • Session state can be used in both multi-computer and multi-process configurations, thereby improving scalability.
  • Session state works with browsers that do not support HTTP cookies, although session state is most commonly used with cookies to provide user identification facilities to a Web application.

In addition to these benefits, you can configure the Session object to use one of the following three backing stores:

  • In process
  • State server
  • SQL Server

Each backing store is described in the following sections.

Note   It is also possible to disable session state storage. To do this, add a <sessionState mode="Off"/> element to the <system.web> section of the Web.config file for your ASP.NET Web application.

Storing State in the In-Process Session Object

Using in-process session state in ASP.NET is closely analogous to using the classic ASP session state and is the default mechanism for managing state in an ASP.NET application. Session state is stored and managed in-process (using the Aspnet_wp.exe process); when that process recycles, the session state that was stored in it is lost.

The main benefit of storing state in-process is performance: the reading and updating of session state occurs much faster when that state information is stored in memory in the same process as the ASP.NET application, because there is no additional overhead for cross-process, network, or database communications.

Use the in-process Session object when:

  • You have to store small or medium amounts of state information.
  • You require high performance data access.
  • You do not require durability; in-process Session object data does not survive computer reboot, IIS reset, or application domain unloading.
  • Your application is hosted on a single server.

Before deciding to use the in-process Session object, consider the following points:

  • In-process session state is the fastest of the three available backing stores for the Session object.
  • The state information cannot be shared between multiple computers. If your application is running in a Web farm, you have to make sure that individual users are pinned to a specific server, or their state information will be lost as they bounce between the various servers in the Web farm.
  • As the amount of state information stored in-process increases, so does the memory required to store that information. As more and more information is added to the in-process session state, the performance of the whole application may be degraded because it takes longer to access and modify the state information.

If in-process session state is appropriate for your application, you can configure it in the Web.config file associated with your ASP.NET Web site.

Note   The settings in Web.config take precedence over any machine-wide settings defined in the machine.config file. If you want to define machine-wide state management settings, edit machine.config instead of Web.config file.

  • If you are using version 1.1 of the .NET Framework, machine.config is located in the %windir%\Microsoft.NET\Framework\v1.1.4322\Config folder.
  • If you are using version 1.0 of the .NET Framework, machine.config is located in the %windir%\Microsoft.NET\Framework\v1.0.3705\Config folder.

To configure the in-process Session object

  1. In the application's Web.config file (or in the computer-wide machine.config file if you prefer), add the <sessionState> element if it is not already there.

  2. In the <sessionState> element, set the mode attribute to "InProc".

    This causes the Session object to be stored in the Aspnet_wp.exe process for the ASP.NET application.

  3. If you want to specify a timeout period after which state for an idle process will be discarded, set the timeout attribute in the <sessionState> element. The default timeout period is 20 minutes.

The following example illustrates these points.

<configuration>
  <system.web>
    <sessionState mode="InProc" timeout="10"/>
  </system.web>
</configuration>
  

This example specifies in-process session management, with a timeout period of 10 minutes.

Storing State in the State Server-based Session Object

Another option for storing session state in an ASP.NET application is out-of-process, by using a state server process. When you use this option, session state is stored in the Aspnet_state.exe process; this process runs as a service and may be located on a separate state server. Using a state server allows applications running in a Web farm to access shared state information.

State information stored in a state server is not lost when a particular application recycles. However, the data is still transient: if the state server recycles, the state information is lost.

Use the state server-based Session object when:

  • You have to share state information between multiple applications or multiple computers.
  • You do not require durability. Data does not survive reboots of the state server.

Before deciding to use the state server-based Session object, you must consider the following points:

  • Using out-of-process session state is slower than in-process session state.
  • The state service does not require authentication.
  • Network traffic between the application and state service is not encrypted. For security reasons, it is best to not run the state service on a server that is directly accessible through the Internet.
  • Communications between applications and the state server use the well-understood (and plain-text) HTTP protocol. It is a good idea to encrypt traffic between the application and state server using Internet Protocol Security (IPSec). For detailed information about IPSec, see Chapter 4 of "Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication" on MSDN (https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/secnetlpMSDN.asp).
  • Information stored in a state server must be serialized; for more information, see "Serializing State" later in this chapter.
  • The IP address or network name of the state server must be specified in Web.config.

If state server-based session state is appropriate for your application, you can configure it in the Web.config file associated with your ASP.NET Web site (or in machine.config)..

To configure the state server-based Session object

  1. Make sure that the state service (Aspnet_state.exe) is running on the state server computer.

  2. The default port used by the state service is the "well-known" port number, 42424, making this an easy target for attack. To change the port number, set the value in the HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\"Port" registry key.

  3. In the Web.config file for your Web application (or in the computer-wide machine.config file if you prefer), add the <sessionState> element if it is not already there.

  4. In the <sessionState> element, set the mode attribute to "StateServer". Also set the stateConnectionString attribute to the IP address or network name of the state server, and indicate the port number the state service is running on.

    Optionally, also set the stateNetworkTimeout attribute to the number of seconds that the ASP.NET Web application will wait for the state server to respond to network requests. The default value is 10 seconds, but there are many factors that might warrant a higher timeout value, such as if the state server or the Web server are overloaded.

The following example illustrates these points.

<configuration>
  <system.web>
    <sessionState mode="StateServer"
                  stateConnectionString="tcpip=myStateServer:42424"
                  stateNetworkTimeout="20"/>
  </system.web>
</configuration>
  

This example specifies state server-based session management. The state service is running on a computer named myStateServer and is accessed through port 42424. A timeout period of 20 seconds has been specified.

Storing State in the SQL Server-based Session Object

Another option for storing session state for ASP.NET applications is to use SQL Server. Using SQL Server to store session state provides several benefits:

  • State can survive SQL Server restarts, if it uses a database other than the default database, TEMPDB.
  • You can share state between multiple instances of your Web application in a Web farm.
  • You can take advantage of clustering; this persists the state if SQL Server stops unexpectedly.

The following sections describe when and how to store state in the SQL Server-based Session object.

Use the SQL Server-based Session object when:

  • You have to share state information between multiple applications or multiple computers.
  • You require fine-grained security control over who is permitted to access the data.
  • Your state information must be durable.

Before deciding to use the SQL Server-based Session object, consider the following points:

  • Using SQL Server for session state also allows user tasks in your application to span multiple sessions and devices.
  • Using SQL Server to store session state is slower than using the in-process and state server-based Session object options.
  • Session state stored in SQL Server must be serialized; for more information, see "Serializing State" later in this chapter.
  • If the connection string used to connect to the SQL state server uses integrated security, your ASP.NET application must use impersonation. For information about how to use impersonation in ASP.NET applications, see Chapter 8 of Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication on MSDN (https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/secnetlpMSDN.asp).
  • SQL Server can use clustering and failover to make sure state data is available.
  • Using SQL Server allows you to perform external backup of long-lived state data.

If SQL Server-based session state is appropriate for your application, you must configure the application to connect to the appropriate database server.

To configure the SQL Server-based Session object

  1. Configure SQL Server to handle Session object state. To do this, run the InstallSqlState.sql script on the computer that is running SQL Server. By default, the script is located in the \systemroot\Microsoft.NET\Framework\version folder.

This script creates the necessary databases, tables, and stored procedures to support session state storage.

  1. In the Web.config file for your Web application (or in the computer-wide machine.config file if you prefer), add the <sessionState> element if it is not already there.
  2. In the <sessionState> element, set the mode attribute to "SQLServer". Also set the sqlConnectionString, to configure the database connection.

The following example illustrates these points.

<configuration>
  <system.web>
    <sessionState mode="SQLServer"
                  sqlConnectionString="datasource=x; user id=y; password=z"/>
  </system.web>
</configuration>
  

Note   If you are using version 1.1.4322 of the .NET Framework, you may choose to run the InstallPersistSqlState.sql script instead of running InstallSqlState.sql. The InstallPersistSqlState.sql script adds state management tables to the ASPState database instead of to the TempDB database, so that session state survives a restart of the state server.

If you use the InstallSqlState.sql script, the SQL state server uses TempDB to store state information. For details about how to configure persistent state in versions of the .NET Framework earlier than 1.1.4322, see article 311209, "HOW TO: Configure ASP.NET for Persistent SQL Server Session State Management," in the Microsoft Knowledge Base (https://support.microsoft.com//).

Using the Session Object

Whichever underlying storage mechanism you choose to use for the Session object, it does not affect how you use the object in your ASP.NET Web application code.

The System.Web.UI.Page class has a Session property that returns a System.Web.SessionState.HttpSessionState object; through this object you can manipulate the contents of the Session object associated with the current user session. State items are held as Object references in HttpSessionState.

The HttpSessionState class provides properties and methods to manipulate the collection's contents, enabling you to add and remove collection elements, get and set specific data elements, enumerate the collection, and clear the collection.

The following code sample shows how to set Session object state, by using the C# indexer of the HttpSessionState class.

Session["username"] = "myUserName";
Session["lastvisit"] = DateTime.Now;
  

The following code sample shows how to get Session object state. Notice the requirement to cast the retrieved data from Object into the required data type.

string userName = Session["username"].ToString();
DateTime lastVisit = (DateTime)Session["lastvisit"];
  

The following section describes how to use cookies as an alternative to the Session object for storing state information.

Storing State in Cookies

A cookie is a small amount of application data stored on the client—either on disk or in memory. The client passes the cookie as part of each request to the application, meaning that the application has access to the data held in the cookie. The application can use the cookie data to make runtime decisions, and it can modify or add to the cookie data before sending the cookie back to the client as part of the application's response.

By default, ASP.NET uses cookies to hold a client's session identifier; this allows ASP.NET to retrieve the correct Session object (discussed earlier). You can also use cookies to store your own state information.

Use cookies when:

  • You have to store small amounts of state information.
  • The state does not include secret or sensitive information.
  • The state does not provide access to or drive secured parts of your application.
  • Your application runs on a server farm and you have no means of providing a centralized state store.
  • The state must survive across page requests or even across application invocations.
  • Your application will still function if the state is not available.
  • You have a relationship with the users and can be confident that they will enable cookies for your application.

Before deciding to use cookies, consider the following points:

  • Cookies can survive across page requests, sessions, application invocations, and even computer reboots.
  • Users can configure their browser to disallow cookies; in this case, your application must provide an alternate mechanism for storing the state information.
  • The user's browser determines how much information a cookie can contain. Individual cookies are limited to a maximum size of 4 KB, and a specific domain may set a maximum of 20 cookies on a user's computer.
  • Information stored in cookies is not durable; the cookie may expire based on information provided by the application or the user. The user can also delete the cookie.
  • Because cookies are stored on the client, the information they contain is subject to modification.
  • Cookies increase network traffic because the cookie is sent as part of each request and response.
  • There is no state maintained on the server between client requests; this is particularly useful in a server farm because you do not have to maintain state centrally.
  • Cookies allow you to set expiration times on the state information, after which the client browser discards the cookie.

Using Cookies

Cookies contain simple name/value string pairs. The easiest way to access cookie state is through the Request.Cookies and Response.Cookies properties of the current System.Web.UI.Page object. Both properties return a System.Web.HttpCookieCollection object containing the set of System.Web.HttpCookie objects that were received from, or will be sent to, the client.

The following code sample shows how to set state information in a cookie.

Response.Cookies["userinfo"]["username"] = "myUserName";
Response.Cookies["userinfo"]["lastvisit"] = DateTime.Now.ToString();
  

The following code sample shows how to get state information from a cookie. Notice the requirement to cast the retrieved data from String into the required data type.

string userName = Request.Cookies["userinfo"]["username"];
DateTime lastVisit = DateTime.Parse(Request.Cookies["userinfo"]["lastvisit"]);
  

Cookies can be a useful way to store state on the client. However, if you cannot guarantee that cookies will be enabled on every client, consider an alternative approach such as hidden form fields or query strings.

Storing State in Hidden Form Fields

Many Web applications store session state information in hidden form fields on the form that the user is currently working on. A hidden form field is not rendered visibly in the browser, but you can set its value property to hold a single piece of page-specific information. When the user re-submits the form to the server, the value of the hidden form field is sent in the HTTP Form collection along with the values of other controls on the form.

Use hidden form fields when:

  • You have to store small amounts of state information.
  • The state does not include secret or sensitive information.
  • The state does not provide access to or drive secured parts of your application.
  • Your application runs on a server farm and you have no means of providing a centralized state store.
  • Cookies are disabled.
  • The state does not have to survive across page requests.
  • Your application will still function if the state is not available.

Before deciding to use hidden form fields, consider the following points:

  • You can encrypt the information stored in hidden form fields to make it harder to attack. However, it is a good idea to use a back-end database to store any sensitive information.
  • You can store only a limited amount of information in a hidden form field; the maximum size is limited by the control you choose for the hidden field.
  • Information stored in hidden form fields is transmitted to the user and increases the size of the download. This can negatively impact performance.
  • Pages must be submitted by way of an HTTP POST. If pages are submitted as an HTTP GET, your Web application will not be able to retrieve the information in the hidden form fields.
  • It is a good idea to never trust data that comes from the user, especially if that data is of a sensitive nature. Some early shopping cart applications stored item price information for their carts in hidden form fields. This information was stored in plain text, and attackers soon realized they could modify the price in the hidden form fields to obtain a discount. Sensitive information should never be stored in hidden form fields, especially in plain text.

The following section describes how to use hidden form fields in an ASP.NET Web page.

To use hidden form fields

  1. Add a hidden field to a form on your ASP.NET Web page.

    One of the ways to do this is to use the HtmlInputHidden control; this control is located on the HTML tab on the Toolbox. When you add this control to your form, an <INPUT> tag is generated as shown in the following example.

    Ff647327.g05diforwc01(en-us,PandP.10).gif

    Note   Another way to add a hidden form field is to use a standard Web Forms control such as a text box, and set its Visible attribute to false. If you adopt this approach, you do not have to perform Steps 2 and 3 in this procedure.

  2. Add a ****attribute to the <INPUT> tag, to enable you to access the hidden control in server-side postbacks. Also add an id attribute, to assign a programmatic identifier for the hidden control.

    Ff647327.g05diforwc02(en-us,PandP.10).gif

  3. In the code-behind file for your ASP.NET Web page, declare an HtmlInputHidden instance variable to correspond to the hidden control. The name of the instance variable must be exactly the same as the id attribute of the hidden control.

    Ff647327.g05diforwc03(en-us,PandP.10).gif

  4. At an appropriate juncture in your ASP.NET Web page, assign a value to the hidden control to store some information in the control.

    The hidden control, and its value, will be returned as part of the response to the client's browser.

    MyHiddenControl.Value = "myUserName";
    
    
  5. On a subsequent postback, retrieve the value of the hidden control and use the information as required.

    string userName = MyHiddenControl.Value;
    
    

Hidden form fields provide a simple mechanism for storing state. A closely related mechanism is to use query strings.

Storing State in Query Strings (URL fields)

The HTTP specification allows for client browsers to pass data as part of the request's query string. This feature is typically used in HTTP GET requests to pass arguments to an application, but you can also use it to pass state information back and forth between the client and server. For example, in the URL https://www.asp.net/somepage.aspx?userid=12\&location=Boston, the query string contains two attribute-value pairs: one named userid and the other named location.

Use query strings when:

  • You have to store small amounts of state information.
  • The state does not include secret or sensitive information.
  • The state does not provide access to or drive secured parts of your application.
  • Your application runs on a server farm and you have no means of providing a centralized state store.
  • Cookies are disabled.
  • The state must survive across page requests or even across application invocations.
  • Your application will still function if the state is not available.

Before deciding to use the query strings to manage state, consider the following points:

  • Some browsers or proxies have URL length restrictions. The current IETF RFC about URL length limits them to 4096 characters.
  • If cookies are disabled, ASP.NET embeds the session ID in the URL of the page, which means the number of characters available for query string state is reduced.
  • Users can easily change the contents of the query string. Make sure that no pages assume authorization, and write code to redirect users to a logon page if they have not already logged on.
  • If the query string values contain characters such as spaces and punctuation, encode the query string values by using HttpUtility.UrlEncode.
  • Use HttpUtility.UrlDecode when reading information from the query string to decode any encoded query string values and to protect against invalid characters in the query string.
  • To make sure people do not modify a query string, it is a good idea to create a keyed hash code for the data.
  • If you want to store sensitive state in the query string, you must use encryption. However, this raises the problem of key management, so it is a good idea to avoid the query string in favor of a more secure state mechanism.

The following procedure describes how to use query strings in an ASP.NET Web page.

To use query strings

  1. Write code in your ASP.NET Web page to programmatically assign a URL to a hyperlink control, form control, image control, or a similar control.

    The URL can contain a query string that relays information to the server-side postback when the user navigates the URL link. For example, the following statement sets the href property on a hyperlink control; the URL contains the user's ID in the query string.

    HyperLinkSubmitOrder.href = "orderVerify.aspx?userid=" + 
                                        HttpUtility.UrlEncode("123 456 <789>");
    
    
  2. On a subsequent postback, retrieve the required information from the query string as shown in the following example.

    string userID = 
       HttpUtility.UrlDecode(Request.QueryString["userid"].ToString());
    
    

Query strings and hidden form fields are generic techniques that are used in many Web technologies. The following section describes an ASP.NET-specific mechanism, whereby state is stored in the ViewState property of an ASP.NET Web page.

Storing State in ViewState

Each ASP.NET page has a ViewState property that is used by the .NET Framework to persist control state between page requests. Every time the application responds to a client request, ASP.NET serializes the content of the page's view state and includes it in the HTML response as a hidden field. When the client submits the next request to the application, the request includes the serialized view state. ASP.NET parses the view state and uses it to set the initial state of the page and the contained controls. You can also use view state to store custom state information for your application

Use view state when:

  • You have to keep track of page-specific information between postbacks.
  • You have to store small amounts of state information.
  • The state does not include secret or sensitive information.

Before deciding to use view state, consider the following points:

  • State stored in the ViewState property is available only to the current page; view state is not persisted across pages.
  • The values in view state are sent to the client, increasing the amount of network traffic.
  • Storing large sets of information in the view state property can slow the rendering of the page and the parsing of requests, because ASP.NET has to manipulate the view state values.
  • When rendered to HTML, the view state values are compressed, encoded and hashed. This improves efficiency by reducing the amount of data sent, and it helps make sure people cannot submit modified view state. However, because the view state is not encrypted, merely encoded, people can easily decompress and decode the view state to obtain the contained data.
  • When using ASP.NET mobile controls to deliver applications to mobile devices, view state is not sent to the client device, but instead it is stored in the Session object automatically by the ASP.NET runtime.

The following procedure describes how to use view state in an ASP.NET Web page.

To use ViewState

  1. Write code in your ASP.NET Web page, to assign a value to a ViewState property for your Web page.

    If a ViewState setting with the specified name does not already exist, it is created automatically. The following example creates a ViewState property named "username," and sets its value to "myUserName."

    ViewState["username"] = "myUserName";
    
    
  2. On a subsequent postback, retrieve the required information from the view state and cast it to the appropriate type.

    string userName = ViewState["username"].ToString();
    
    

Using view state in this way makes it easy to persist small amounts of state between page postbacks on pages where controls have server-side event handlers.

Storing State in the Application Object

The System.Web.UI.Page class, that all ASP.NET pages inherit from, provides an Application property through which you can share state between all users and all sessions of an application.

Use the Application object when:

  • You have to manage application-wide state that is not specific to any particular user or session.
  • The state does not have to survive the life of the process the application is running in.
  • The state is sensitive and cannot be passed across the network.
  • You have substantial amounts of read-only state that you can load into the Application object at the start of application execution. An alternative solution might be to cache the data; for more information, see "Caching State" later in this chapter.

Before deciding to use the Application object, consider the following points:

  • The Application object is a dictionary-based, in-memory storage mechanism, meaning that it is fast, but storing large amounts of data affects the performance of your server.
  • Because the state is stored on the server, the Application object offers higher levels of security than the client-based state mechanisms such as cookies, hidden form fields, and query strings; however, because all application code can access the Application object, it does not provide as secure a solution as the Session object.
  • You must synchronize access to Application state data, because other threads may be accessing the state at the same time. This means the Application object is best for read-only state.
  • Unlike the Session object, you cannot specify a timeout value after which the Application object state expires. Data in the Application object is retained until you remove it or until the application terminates.

The following section describes how to store state in the Application object.

Using the Application Object

The System.Web.UI.Page class has an Application property that returns a System.Web.HttpApplicationState object; through this object, you can manipulate the contents of the Application object. State items are held as Object references in HttpApplicationState.

The HttpApplicationState class provides properties and methods to manipulate the collection's contents, enabling you to add and remove collection elements, get and set specific data elements, enumerate the collection, and clear the collection.

The following code sample shows how to access Application object state, by using the C# indexer of the HttpApplicationState class.

Application.Lock();
if (Application["hitCount"] == null)
{
  Application["hitCount"] = 1;
}
else
{
  Application["hitCount"] = 1 + (int)Application["hitCount"];
}
Application.UnLock();
  

Note the use of the Lock and UnLock methods to serialize access to the Application object state. Note also that the data is cast to the appropriate data type (in this case an integer) when retrieved.

Serializing State

When you store state out-of-process, such as in a state server or in SQL Server, the data must be serialized. Depending on the type of data that you store, this might lead to a major performance hit.

If you store basic types such as integers, strings, and GUIDs, the .NET Framework uses optimized methods to serialize the data. However, if you want to store non-trivial types such as a Hashtable, the framework uses the BinaryFormatter by default to perform serialization. This method of serialization is slower than that used for basic types.

To enable custom types to be serialized

  1. Annotate your custom type with the [Serializable] attribute.

    For example, the following code defines a serializable class named CustomerDetails.

     [Serializable]
    public class CustomerDetails
    {
      // Plus other members ...  
    }
    
    
  2. Declare fields, properties, and methods in the class as usual.

    Note that BinaryFormatter serializes all the fields of a class—even fields marked as private. In this respect, binary serialization differs from the XmlSerializer class; the XmlSerializer class serializes only public fields.

  3. If you want selective fields to be excluded from binary serialization, annotate the fields with the [NonSerialized] attribute.

    The following example defines three fields; the mName and mAddress fields will be serialized, but the mLastUpdate field will not be serialized.

     [Serializable]
    public class CustomerDetails
    {
      private string mName;
      private string mAddress;
      [NonSerialized] private DateTime mLastUpdate;
      // Plus other members ...  
    }
    
    

If your custom type is particularly large, or if it contains information that can be summarized into a more concise format, consider defining a custom serialization format for your type.

To define a custom serialization format

  1. Implement the ISerializable interface in your custom type.
  2. Provide a GetObject method to define how you want the object's information to be serialized.
  3. Provide a deserialization constructor to enable a copy of the object to be reconstituted during deserialization.

For more information about how to perform custom serialization, see "Custom Serialization" on MSDN (https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcustomserialization.asp).

Caching State

Caching is a technique used to improve the performance and scalability of applications. Caching is most useful in server-based applications, in particular Web applications, but it also applies to many smart client situations. The purpose of caching is to keep state that is expensive to create or retrieve in a more easily accessible form or location. For example, when a user has an active session on your Web application, if you keep a copy of their profile in memory instead of always reading from a remote SQL Server, your application performance improves.

You must consider your caching requirements when you design the state management aspects of your application. Caching can be difficult to implement in an existing application, and the capabilities of the caching mechanism must be appropriate to the lifetime, scope, and type of state you have to manage.

A complete discussion of caching is beyond the scope of this guide. For comprehensive coverage, see the "Caching Architecture Guide for .NET Framework Applications" on MSDN (https://msdn.microsoft.com/en-us/architecture/default.aspx).

Summary

State management is a crucial consideration in Web applications. You must choose the appropriate storage locations and mechanisms to manage state in your presentation layer to attain the optimal levels of security, scalability, manageability, and extensibility.

Start | Previous | Next

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

© Microsoft Corporation. All rights reserved.