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. |
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
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.
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.
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
Make sure that the state service (Aspnet_state.exe) is running on the state server computer.
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.
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.
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
- 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.
- 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.
- 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
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.
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.
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.
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.
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";
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
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>");
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
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";
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
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 ... }
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.
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
- Implement the ISerializable interface in your custom type.
- Provide a GetObject method to define how you want the object's information to be serialized.
- 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.
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. |