Previous Section  < Day Day Up >  Next Section

17.4. Maintaining State

The standard for the HTTP protocol is contained in a document known as RFC 2616. In printed form, it is more than 120 pages in length. If you search this document, you'll find that not one page, section, or sentence discusses a method for maintaining state information between HTTP requests. The term cookie is completely absent. So, unlike human memory where "our thoughts are linked by many a hidden chain" (Alexander Pope), the Internet protocol is designed to be stateless梕ach request unlinked to the preceding one.

Yet, for Internet applications to flourish, a means has to exist to identify specific users. Online purchasing, surveys, and the need to recognize user preferences depend on it. The first efforts to maintain state information relied on using features defined in the HTTP protocol: hidden fields that could be sent back and forth using the POST method, and a string full of values that could be placed after the ? character in an HTTP URL path. The former technique is used to maintain .NET ViewState information; the latter constitutes a "query string" consisting of name/value pairs.

A third client-side approach to managing state is the use of cookies, a small (4K) text-only string that is stored in browser memory during a session and may be written to disk. Many applications maintain session-related state information, such as a shopping cart's identification, in cookies. ASP.NET identifies each session by creating a cookie containing a unique session ID.

These approaches are plagued by a common weakness: They can be compromised by the client. Query strings and hidden fields can be altered; cookies can be altered or simply turned off on the browser.

To overcome these shortcomings, ASP.NET offers two general types of server-side state management: session state, which maintains information for the life of the session; and application state, which maintains information across multiple sessions. Although these techniques maintain information on a server梤ather than passing it back and forth between requests梩hey still rely on a cookie, where possible, to uniquely identify a user's session. However, the server-based solution presents another problem: All session activity must be handled by that server possessing the state information. This is incompatible with large Web sites where a server-selection algorithm assigns requests to any machine in a Web farm. An ASP.NET solution to this is the use of a central database to store session state information.

Table 17-4 summarizes the client- and server-side state management approaches. Of those listed, this section focuses on the application and session management techniques.

Table 17-4. State Management Techniques for Web Applications

Technique

Web Farm

Compatible

Description

Query String

Yes

Data passed as part of URL.

View State

Yes

ASP.NET hidden View_State field used.

Cookie

Yes

Information passed to/from browser in a cookie.

Application

No

An Application object maintains information available to all sessions accessing an application.

Session: In-Process

No

Session state is stored and managed using the Aspnet_wp.exe process.

Session: State Server

Yes

Session state is stored in the Aspnet_state.exe process.

Session: SQL Server

Yes

State information is maintained in a temporary table in a database.


Application State

Application state data is maintained in an instance of the HttpApplicationState class梐n in-memory dictionary holding key-value objects. The contents of this dictionary object are available to all sessions using that application.

The data is usually loaded within the global.asax file when the Application_ Start event fires.


protected void Application_Start(object sender, EventArgs e)

{

   Application["targetBMI"]= 21; 

   Application["obeseBMI"] = 26; 

}


Users of the application then have read and write access to the data without having to regenerate it. This is particularly useful when working with data from a database. It can also be a convenient way to initialize variables used for collecting usage statistics. (See Section 17.2 for background on global.asax file.)

Accessing and Updating Application State Data

All sessions using the application may access the Application object through the Application property of the System.Web.UI.Page type. The only thing to note about accessing data is that it must be cast, because the information is stored as an object. Here is a segment that illustrates the primary properties and methods for working with the Application object:


int target = (int) Application["targetBMI"];

// Change value

Application["targetBMI"] = 22;

// List all HttpApplicationState values

foreach( string s in Application.AllKeys){

       Response.Output.Write("<br>{0} = {1}",s,Application[s]);

}

// Remove Application item

Application.Remove("obeseBMI");


Not illustrated are the Lock and UnLock methods that allow application variables to be updated in a thread-safe manner.

Considerations in Using Application State

The variables contained in application state have two primary uses: as read-only data globally available across all of the application's sessions, and as variables that are updated to keep statistics regarding the application's use. Both of these uses can be handled more efficiently using a different approach.

The ASP.NET data cache provides a more flexible approach for making read-only data available on an application-wide basis. Its contents are as accessible as those in the application object, and it offers the advantage of having its contents automatically refreshed at a specified time interval. (Its use is described in Section 17.5.) As a rule-of-thumb, use application state to preload small amounts of read-only data required by an application; use the data cache when working with large amounts of data.

The problem with maintaining usage data in application state is that the data is available only during the life of the application. When it ends, the data is gone. In addition, if there are multiple servers, the data will apply to only one server. A better approach is store the information in a central database.

Core Note

Application recycling refers to shutting down and restarting an application based on criteria such as time, memory usage, and number of client requests. It is set using the <processModel> tag in the web.config file. The following setting recycles the application every two hours.


<processModel timeout="120">



Session State

When a new client requests an ASP.NET application, ASP.NET creates a cookie containing a unique session ID and returns it to the client's browser. This ID, or session key, is used to identify subsequent requests from the client. State information unique to each session is maintained in an instance of the HttpSessionState object. The contents of this object are available through the Session properties of both the Page and HttpContext class. Note that Session can be used in place of the fully qualified HttpContext.Session. Working with session state is analogous to working with application state. Many applications perform state session initialization in a Session_Start event handler in the global.asax file. This segment initializes variables for an online survey:


// global.asax file

protected void Session_Start(object sender, EventArgs e)

{

   Session["Start"]= DateTime.Now; 

   Session["QuestionsAnswered"] = 0; 

}


The variables can be updated in the application with the same syntax used for the Application object:


int ict= (int)Session["QuestionsAnswered"]+1;

Session["QuestionsAnswered"]=ict;


The HttpSessionState class contains several members that are useful in manipulating and interrogating the Session object. The following code demonstrates their use:


// Session ID is unique to each session

Response.Write("<br>Session ID: "+Session.SessionID);

// Mode may be InProc, StateServer, SqlServer, Off

Response.Write("<br>Processing Mode: "+Session.Mode);

// Session times out after 20 minutes (default) of inactivity

Response.Write("<br> Timeout: "+Session.Timeout);

// Number of items in session state

Response.Write("<br>Items: "+Session.Count);

// List key-values in session state

foreach( string key in Session.Keys) 

      Response.Output.Write("<br>{0} = {1}",key, Session[key]);


The most interesting of these properties, by far, is Session.Mode, which indicates where the Session object is configured to store its data. Session state information can be stored using one of three methods: InProc, StateServer, or SqlServer. Although the choice does not affect the way information is accessed through the Session object, it does affect application performance, manageability, and extensibility. Let's look at the details of using all three backing stores (see Figure 17-6).

Figure 17-6. Session state data store options


In-Process Session State

By default, ASP.NET stores session state in-process using the aspnet_wp.exe process. This means that the information is managed in memory space where the application is running. This has the advantage of providing fast access to the data. The drawbacks are that it must run on a single server梡recluding its use with Web farms梐nd that all session data is lost if the server reboots. Given this, it is recommended for single-server sites that need to maintain moderate amounts of data in state.

To select in-process session state management, set the mode attribute to InProc in the <sessionState> element of the web.config file. As shown here, you can also specify a time limit specifying how long the process may be idle before the session data is discarded.


<configuration>

   <system.web>

      <sessionState mode="InProc" timeout="30"/>

   </system.web>

</configuration>


Out-of-Process Session Using a State Server Process

The concept of out-of-process session state management entails the use of a mechanism outside of the application's process to store state data. ASP.NET provides two such mechanisms: a separate process running on a selected state server and the use of a data server to store state information.

When session state mode is used, session state is stored in the Aspnet_ state.exe process. This allows an application running on multiple servers to share state information. Because the server running this process is accessed via a network on the Internet, performance is slower than using the in-process approach. Also, the data is susceptible to a server reboot.

To access a state server, make sure the machine selected is running the Aspnet_state.exe process. Any server accessing the state server must set the <sessionState> element in its web.config file to point to the state server. The default port used is 42424. On a Windows-based operating system, this can be changed through the registry.


<configuration>

   <system.web>

      <sessionState mode="StateServer"  

         stateConnectionString="192.168.1.109:42424"

      />

   </system.web>

</configuration>


Out-of-Process Session Using SQL Server

Using a SQL Server database to store session state data also offers the capability of sharing data among machines. In addition, SQL Server security features can be used to selectively provide access to the data; and, of course, the data is not transient because it exists in tables. The disadvantages of this approach are that it only works with Microsoft SQL Server and it is the slowest of the three session state modes.

To prepare a machine running SQL Server to handle session state requires no more than creating the tables that ASP.NET expects. The InstallPersistSqlState.sql script takes care of this. By default, the script is located in the \systemroot\Microsoft.NET\Framework\version folder. It creates a database named ASPState that contains the state tables.

Web.config is used to tell ASP.NET that session information for the application(s) is stored on a SQL Server. The <sessionState> element is set to specify the mode and connection string.


<configuration>

  <system.web>

    <sessionState mode="SQLServer"

      sqlConnectionString="datasource=x; user id=sa; password="/>

  </system.web>

</configuration>


SQL Server should be considered when there is a need to maintain data beyond the life of the session. For example, sites often persist the content of a shopping cart so it is available when the user logs in again.

Because the use of SQL Server slows Web page performance, it should be used only on those pages in an application that require state data. The @Page directive has an EnableSessionState attribute that dictates how state is used on the page. It can be set to false to disable session state, TRue to enable read and write session state, or readOnly.

    Previous Section  < Day Day Up >  Next Section