ASP.NET Session State


Session state still exists in ASP.NET, partly for backward compatibility, but also as a viable implementation that developers should no longer shy away from. ASP.NET session is free-threaded, but in some cases it can be accessed serially. Session state in ASP.NET still utilizes an HTTP cookie for managing the SessionID, however, ASP.NET also supports storing the SessionID in the URL if using cookies is not desirable. ASP.NET session state also supports two out-of- process modes to simplify deployment in Web server farms: out-of-process state server (StateServer), and out-of-process SQL Server (SQLServer).

In-Process Session State

ASP.NET defaults to what is known as in-process (InProc) session state. When in this mode, values stored within session state do not require serialization support and are stored within the memory space of the ASP.NET worker process. This behavior is identical to the way ASP stores its session data and has all the same shortcomings and limitations in a Web farm scenario. However, instead of the data being stored in the IIS process, the data is stored in managed memory within the ASP.NET worker process. (When ASP.NET is running on Microsoft Windows 2000, it defaults to the ASP.NET worker process aspnet_wp.exe. However, when ASP.NET is running on Microsoft Windows Server 2003, it will use the new IIS process model w3wp.exe.)

When stored in-process, session state data is lost whenever the process is recycled. In Microsoft Windows Server 2003 running IIS 6, the worker process automatically recycles every 29 hours, which is the default setting and is configurable. However, this does mean that every 29 hours the session data will be lost, whether it is 2:00 AM or 3:00 PM.

InProc is by far the fastest way to use session state. It doesn’t support Web farm scenarios (unless you enforce client affinity). However, it also doesn’t have the serialization and deserialization overhead associated with out-of-process modes. It’s safe to assume that out-of-process session state is 15–30 percent slower (depending upon variables such as network speed and the size of the object or objects being serialized).

Important

Use in-process session state (the default) if you have only a single server. In IIS 6, either use out-of-process or disable process recycling behavior to avoid data loss.

Code Listing 5-1 shows the configuration settings from machine.config that specify the default settings for session state. Values that apply to InProc appear in bold.

Code Listing 5-1: In-Process Session State Configuration

start example
 <configuration>
<system.web>
<sessionState mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10"
sqlConnectionString="..."
cookieless="false"
timeout="20" />
</system.web>
</configuration>
end example

The timeout value specifies the time, in minutes, after which a session is considered timed out and its values can be removed. Session state uses a sliding expiration: the timeout is reset each time the item is requested. A session could theoretically be kept alive indefinitely if a request was made just once before the value in the timeout is reached. We’ll discuss the cookieless option later in the chapter.

The name of the HTTP cookie used to store the SessionID in ASP.NET is different from the cookie used to store the SessionID in ASP. There is no sharing of session data between ASP and ASP.NET. (See Chapter 11 for more details about migrating session state between ASP and ASP.NET.)

InProc session state allows any data type to be stored, and it participates in the global session events Session_OnStart, which is raised when a new session is created; and Session_OnEnd, which is raised when a session is abandoned. These events can be programmed in either global.asax or within an HTTP module.

Important

Don’t use the Session_End event; it can be called only for sessions created in the InProc mode. The event is not raised for sessions created in one of the out-of-process modes when sessions are abandoned.

Although the InProc session is the fastest, in some cases, you might want to trade performance for reliability or ease of management. For example, the out-of-process option is a good choice when you want to support multiple Web servers, or when you want to guarantee that session data can survive the Web server process.

Out-of-Process Session State

ASP.NET session state supports two out-of-process options, state server (StateServer) and SQL Server (SQLServer). Each has its own configuration settings and idiosyncrasies to contend with, such as managing stored types. The ASP.NET State Service is recommended for medium-size Web applications. For enterprise-size or highly-transactional Web applications, SQL Server is recommended.

Important

It’s important that the programming model is transparent. For example, we don’t have to change how we access or use session state when we change the storage mode.

We recommend SQLServer for out-of-process session state because it is just as fast as StateServer and SQL Server is excellent at managing data. Furthermore, ASP.NET can communicate with SQL Server natively (meaning internally, using the System.Data.SqlClient libraries), and SQL Server can be configured to support data failover scenarios. In cases in which SQLServer is not available, StateServer works well, but it unfortunately does not support data replication or failover scenarios.

Managing Types for Out-of-Process Modes

If you’re using an out-of-process mode, one of your major costs is the serialization and deserialization of items stored. Using an optimized internal method, ASP.NET performs the serialization and deserialization of certain “basic” types, including numeric types of all sizes, such as Int, Byte, and Decimal, as well as several non-numeric types, such as String, DateTime, TimeSpan, Guid, IntPtr, and UintPtr.

If you have a session variable that is not one of the basic types, ASP.NET will serialize and deserialize it using the BinaryFormatter, which is relatively slower than the internal method. If you’ve created a custom class, and you want to store it in session state, you must mark it with the [Serializable] meta-data attribute or implement the ISerializable interface. ([Serializable] is the C# metadata attribute. <Serializable()> is the Microsoft Visual Basic .NET metadata attribute.) The SerializableAttribute class is defined in the mscorlib.dll assembly within the System namespace. The ISerializable interface is defined in the assembly mscorlib.dll and within the System.Runtime.Serialization namespace. When a class is marked with the SerializableAttribute, all public members will attempt to be serialized. If the class contains references to other objects, those objects must also be marked with the SerializableAttribute or implement ISerializable. Implementing ISerializable gives you more control over how the serialization and deserialization of your class takes place. For more details on the serialization of objects in Visual Basic .NET, visit http://www.fawcette.com/reports/vsliveor/2002/09_18_02/hollis/.

For the sake of performance, you’re better off storing all session state data using only one of the basic data types (numeric and non-numeric types) listed earlier. For example, if you want to store a name and address in session state, you can store them using two String session variables, which is the most efficient method; or you can create a class with two String members and store that class object in a session variable, which is more costly.

Important

Store only basic data types in session state; avoid storing complex types or custom classes. Storing basic data types will decrease the serialization and deserialization costs associated with out-of-process session as well as reduce the complexity of the system.

Now that you’ve had an overview of out-of-process session, let’s discuss the two out-of-process modes, StateServer and SQLServer.

StateServer Mode

The StateServer out-of-process mode relies on a running Microsoft Windows NT Service as well as changes to the default configuration settings. Code Listing 5-2 shows machine.config with the necessary configuration settings (which appear in boldface) for StateServer. Note that the mode attribute is set to StateServer. The stateConnectionString and stateNetworkTimeout settings are required values for StateServer mode.

Code Listing 5-2: StateServer Session State Configuration

start example
 <configuration>
<system.web>
<sessionState mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10"
cookieless="false"
timeout="20"/>
</system.web>
</configuration>
end example

When ASP.NET is configured to use state server for out-of-process session, it uses a TCP/IP address and port number to send HTTP requests to the state server (which is in fact a lightweight Web server running as a Microsoft Windows Service).

The IP address (in stateConnectionString) must be changed to the IP address of the machine running the ASP.NET State Service. The port (the default is 42424), should also be changed unless the state service is running behind a firewall (which it should be). The port number can be configured on the machine running the service by editing the registry and changing the value of the port setting found in the following:

HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\ 

As seen in Figure 5-1, the default setting for the port is 0x0000A5B8 in hexadecimal, or 42424 in base 10.

click to expand
Figure 5-1: Changing the default port in the registry

Tip

If the server running the state service is accessible outside the firewall, the port address of the state service should be changed to a value other than the default. In version 1.1 of ASP.NET, due to security reasons, only local machines can connect to the state server. To allow only non–local host requests in ASP.NET 1.1, open the same registry entry listed earlier for the port setting: HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\. Change AllowRemoteConnection to 1.

The value of stateNetworkTimeout represents the number of seconds that may elapse between the time ASP.NET tries to connect to the state service and the time the request times out. Although the default value for stateNetworkTimeout does not need to be changed, you have the option to make the value higher or lower depending upon your requirements.

Once the server designated to run the state server has been properly configured, it is simply a matter of starting the Windows service. The service can be started from either the command line or the Microsoft Management Console (MMC) for Services.

Starting the state service from the command line is simple. Navigate to the .NET Framework installation directory. For version 1, this is [system drive]\WINDOWS\Microsoft.NET\Framework\v1.0.3705\. Start the server by executing a net start command:

net start aspnet_state  

After starting the service, you should see the following text: “The ASP.NET State Service service is starting. The ASP.NET State Service service was started successfully.”

The second option for starting the state service is through the Services MMC snap-in, which you open by navigating to Start\Administrative Tools\Services. Right-click on the ASP.NET State Service option in the list and select Start to start the service. Once the Services MMC is started, you should see a screen similar to Figure 5-2.

click to expand
Figure 5-2: Services MMC with ASP.NET state service started

SQL Server Mode

SQL Server is an enterprise-class database solution optimized for managing, storing, and retrieving data quickly and efficiently. It is also capable of replication and clustering. In a clustered environment, SQL Server can be configured to failover. For example, when the clustered production SQL server fails, a backup can take over.

Note that clustered SQL Server scenarios are not supported out of the box for ASP.NET session state. To enable the clustering or replication features of SQL Server, session data must be stored in a non-tempDB table.

Again, you do not need to make any special changes to the code to use SQL Server as the session state store. Code Listing 5-3 shows the necessary configuration file machine.config for SQL Server. (Configuration changes are in boldface code.)

Code Listing 5-3: SQL Server Session State Configuration

start example
 <configuration>
<system.web>
<sessionState mode="SQLServer"
sqlConnectionString="database=[ServerName];
Trusted_Connection=true"
cookieless="false"
timeout="20"/>
</system.web>
</configuration>
end example

The mode attribute needs to be SQLServer, and the sqlConnectionString attribute must point to a server running SQL Server that has already been configured for ASP.NET SQL session state.

Tip

For ASP.NET 1, configure SQL Server for mixed-mode authentication by adding the ASPNET account enabled for the necessary SQL Server permissions (EXECUTE) for ASP.NET session state. (The ASPNET account is the user that the ASP.NET worker process runs as.) For ASP.NET 1.1 running on IIS 6, configure SQL Server for mixed-mode authentication by adding the NT AUTHORITY\NETWORK SERVICE account.

If the account has the necessary permissions, integrated authentication should be used. This prevents the need to store a username and password in clear text within the configuration. When integrated authentication is used, ASP.NET accesses SQL Server using the credentials of the Windows user that the worker process runs as. By default, these credentials are ASPNET and NT AUTHORITY\NETWORK SERVICE on Windows Server 2003 running IIS 6.

Important

Use integrated authentication rather than store SQL Server credentials within your configuration file. If you decide to use SQL Server user names and passwords, do not use the system administrator (sa) account. Instead use an account that has only the necessary access to the database object required for the operations (for session state, this account is EXECUTE only). If you must use SQL Server credentials, ASP.NET 1.1 supports storing credentials securely.

To configure SQL Server to support ASP.NET session state, either open the InstallSqlState.sql file in isqlw.exe (Microsoft SQL Server Query Analyzer), or use the command-line tool osql.exe. To use SQL Server Query Analyzer, from the Start menu, navigate to \All Programs\Microsoft SQL Server\Query Analyzer. The SQL Query Analyzer application appears in Figure 5-3.

click to expand
Figure 5-3: SQL Query Analyzer

Important

Ensure SQL Server Agent is running before running the SQL Scripts. The agent runs a periodic job to purge expired sessions from the database.

If you’re running ASP.NET 1, from the toolbar select File | Open [system drive]\WINDOWS\Microsoft.NET\Framework\v1.0.3705\ InstallSqlState.sql. If you’re running ASP.NET 1.1, navigate to [system drive]\WINDOWS\Microsoft.NET\Framework\v1.0.4322\ directory and open the same file. Execute the script, either by clicking the Play button or by pressing F5. Using the command-line tool (osql.exe), open a command window and then navigate to \[system drive]\WINDOWS\Microsoft.NET\Framework\[ASP.NET version]\.

If integrated authentication is enabled for SQL Server and the current Windows logged-on user has permissions to SQL Server, type the following: osql -E < InstallSqlState.sql.

If SQL Server mixed-mode authentication is enabled and the current logged- on user does not have permissions within SQL Server, specify a user name and password using osql - U [sql user] - P [password] < InstallSqlState.sql.

After running the SQL Script, SQL Server is configured to support ASP.NET session state. Two tables are created within the tempdb database: ASPStateTempApplications and ASPStateTempSessions.

Note

Why do we use tempdb? We often get asked why we store session data using tempdb vs. a table. The original design goal was to ensure that SQL Server state was fast, and because tempdb is memory-based, SQL Server state would be very fast. However, since SQL Server is so optimized, storing the data in non-temporary tables proved to be nearly as efficient. (SQL Server is super aggressive about keeping frequently accessed data in memory.) In retrospect, using tempdb probably wasn’t necessary.

Session Data in a Web Farm

The major benefit of out-of-process session is that it no longer requires client/ server affinity. Servers in an ASP.NET Web server farm can be configured to share session data. (However, individual applications cannot share session data because a session is tied to a single application.)

To configure session support in a Web farm, you must take one additional step regardless of whether a session is even used: you must configure the machineKey settings. Machine-wide settings are configured in the machine.config file (\[Windows Directory]\Microsoft.NET\Framework\[Versions]\Config\). The machineKey settings store the validationKey and the decryptionKey attribute values, which are used in many scenarios—for example, ViewState, Forms authentication, and session—to provide encryption and validation of values sent back and forth from client to server.

By default, the values for the validationKey and decryptionKey attributes are set to AutoGenerate, which enables the server to randomly create the values. Randomly selected values work well in a single server environment; however, in a Web server farm in which there is no guarantee which server will satisfy the client’s request, the values for validationKey and decryptionKey must be precise and predictable.

Optimizing Out-of-Process Session Use

When using out-of-process session, ASP.NET makes two requests to the out-of- process session store for every one page requested (if the request comes in with a session ID). When the request first starts, the session state module connects to the state store, reads the session state data, and marks the session as locked. At this point the page is executed, and the Session object is accessible. When the page completes execution, the session state module connects to the state store, writes the session state data if it changed, and unlocks the session data.

The locking mechanism implemented is a reader-writer lock using the ReaderWriterLock class. Multiple requests can read data simultaneously when the session isn’t locked. If the session is locked, read requests are blocked until the write lock is released. This locking strategy guarantees that the Session object with which the user is interacting is always an accurate reflection of the data. If you attempt to build a site that uses frames, and each page within a frame requires session state, the pages will execute serially. You can configure session state to be read-only on a page-by-page or even application basis. Configuring a page to use session data in a read-only manner allows the page to be requested without locking the session data and prevents serialized access.

If session is configured as read-only, in out-of-process mode, the session module does not need to go back to the session store to release the lock. Multiple requests can read session data simultaneously without serialized access, which yields better throughput. To configure the read-only option on a page- by-page basis, simply set the page-level directive EnableSessionState:

<%@ Page EnableSessionState="ReadOnly” %>  

Another option is to configure session to enableSessionState=“false” as the default setting (you can change this in web.config or machine.config) and use EnableSessionState=“ReadOnly” or EnableSessionState=“true” at the page level. Code Listing 5-4 shows the code for disabling session state.

Code Listing 5-4: Disabling Session State

start example
 <configuration>
<system.web>
<pages enableSessionState="false" />
</system.web>
</configuration>
end example

Important

For out-of-process session, set session state to enableSessionState=“false” within the configuration file and set the EnableSessionState page directives to either true or ReadOnly based on what behavior is needed. Note that the length of the session will still be reset (even when set to false).

When you apply this strategy for optimizing out-of-process session, you get fewer requests to the out-of-process session store, which increases the scalability and throughput of the site.

Cookieless Session

Session state, to HTTP purists, is a frowned upon but necessary feature for building real-world Web applications. Session state was designed to work around the limitations of the stateless nature of HTTP. To do so, the browser and the server must share a common piece of data: the SessionID. This shared value must be stored somewhere—we’re certainly not going to ask the user to re-enter an ID value upon each request to the server! To solve this problem, we take advantage of another HTTP feature known as a cookie, which you learned about briefly earlier in the chapter.

A cookie is a highly contentious, much debated feature supported by all browsers that allows the server to store a small amount of data, private to the server, on the client. Upon each client request to the server, the browser sends along any cookie data belonging to that server.

For both ASP and ASP.NET, the SessionID is stored within a cookie. When the client makes requests to the server, the client presents the cookie, giving ASP.NET the opportunity to fetch any associated session data belonging to the presented SessionID.

Important

Using the SessionID as a key for user data is not recommended. The SessionID is randomly generated, and session data—as well as session IDs—do expire. Additionally, although a SessionID might be generated on each request, a SessionID is set only when a Session value is set server side. This means that if no session values are set server side, new SessionIDs are issued on each request.

Storing the SessionID in a cookie works very well except when the client chooses not to accept cookies. (By default, cookies are accepted, and the user has to explicitly disable cookie support to avoid using them.) When cookies are not supported, ASP.NET provides a cookieless option in which the SessionID is stored within the URL instead of an HTTP cookie.

An ASP.NET Web application cannot be configured to support both cookie and cookieless SessionID storage; that is, the application cannot dynamically choose whether to use cookies. This can be seen as advantageous because designing an application to accommodate various cookie scenarios can be very difficult.

When building applications to take advantage of a cookieless session, you must carefully design navigation in the user interface. Any links within the site that are not relative (those starting with http://) will cause the user to lose her session when clicked. For relative URLs (for example, /MyStore/default.aspx), the embedded SessionID is automatically added by ASP.NET when generating the page output.

Tip

If you have to develop an application that supports both cookie and cookieless sessions, your best strategy is to write an HTTP module to redirect the browser to the appropriate application or server for the supported browser feature, for example, configure a dedicated application that is used for cookieless sessions.




Microsoft ASP. NET Coding Strategies with the Microsoft ASP. NET Team
Microsoft ASP.NET Coding Strategies with the Microsoft ASP.NET Team (Pro-Developer)
ISBN: 073561900X
EAN: 2147483647
Year: 2005
Pages: 144

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net