For example, you might want to end a user session automatically when a user logs out from your appli-cation to clear away all of a user’s session state information.. Handling Session Eve
Trang 1</form>
</body>
</html>
In Listing 28.11, a DataView object is stored in Session state When you sort the GridView
control, the DataView is sorted
The page in Listing 28.11 includes a link that enables you to reload the page The sort
order of the records displayed by the GridView is remembered across page requests The
sort order is remembered even if you navigate to another page before returning to the
page
Using the Session Object
The main application programming interface for working with Session state is the
HttpSessionState class This object is exposed by the Page.Session, Context.Session,
UserControl.Session, WebService.Session, and Application.Session properties This
means that you can access Session state from just about anywhere
This HttpSessionState class supports the following properties (this is not a complete list):
CookieMode—Enables you to specify whether cookieless sessions are enabled Possible
values are AutoDetect, UseCookies, UseDeviceProfile, and UseUri
Count—Enables you to retrieve the number of items in Session state
IsCookieless—Enables you to determine whether cookieless sessions are enabled
IsNewSession—Enables you to determine whether a new user session was created
with the current request
IsReadOnly—Enables you to determine whether the Session state is read-only
Keys—Enables you to retrieve a list of item names stored in Session state
Mode—Enables you to determine the current Session state store provider Possible
values are Custom, InProc, Off, SqlServer, and StateServer
SessionID—Enables you to retrieve the unique session identifier
Timeout—Enables you to specify the amount of time in minutes before the web
serv-er assumes that the usserv-er has left and discards the session The maximum value is
525,600 (1 year)
The HttpSessionState object also supports the following methods:
Abandon—Enables you to end a user session
Clear—Enables you to clear all items from Session state
Remove—Enables you to remove a particular item from Session state
Trang 2The Abandon() method enables you to end a user session programmatically For example,
you might want to end a user session automatically when a user logs out from your
appli-cation to clear away all of a user’s session state information
Handling Session Events
There are two events related to Session state that you can handle in the Global.asax file:
Session Start and Session End
The Session Start event is raised whenever a new user session begins You can handle
this event to load user information from the database For example, you can handle the
Session Start event to load the user’s shopping cart
The Session End event is raised when a session ends A session comes to an end when it
times out because of user inactivity or when it is explicitly ended with the
Session.Abandon() method You can handle the Session End event, for example, when
you want to automatically save the user’s shopping cart to a database table
The Global.asax file in Listing 28.12 demonstrates how you can handle both the Session
Start and End events
LISTING 28.12 Global.asax
<%@ Application Language=”C#” %>
<script runat=”server”>
void Application_Start(object sender, EventArgs e)
{
Application[“SessionCount”] = 0;
}
void Session_Start(object sender, EventArgs e)
{
Application.Lock();
int count = (int)Application[“SessionCount”];
Application[“SessionCount”] = count + 1;
Application.UnLock();
}
void Session_End(object sender, EventArgs e)
{
Application.Lock();
int count = (int)Application[“SessionCount”];
Application[“SessionCount”] = count - 1;
Application.UnLock();
}
</script>
Trang 3In Listing 28.12, the Global.asax file tracks the number of active sessions Whenever a
new session begins, the Session Start event is raised and the SessionCount variable is
incremented by one When a session ends, the Session End event is raised and the
SessionCount variable is decremented by one
The SessionCount variable is stored in Application state, which contains items shared
among all users of a web application The Application object is locked before it is
modi-fied You must lock and unlock the Application object because multiple users could
potentially access the same item in Application state at the same time
NOTE
Application state is little used in ASP.NET applications In most cases, you should use
the Cache object instead of Application state because the Cache object is designed
to manage memory automatically
The page in Listing 28.13 displays the number of active sessions with a Label control (see
Figure 28.5)
FIGURE 28.5 Displaying a count of user sessions
Trang 4LISTING 28.13 ShowSessionCount.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<script runat=”server”>
void Page_Load()
{
lblSessionCount.Text = Application[“SessionCount”].ToString();
}
</script>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show Session Count</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
Total Application Sessions:
<asp:Label
id=”lblSessionCount”
Runat=”server” />
</div>
</form>
</body>
</html>
WARNING
The Session End event is not raised by all session store providers The event is
raised by the InProc session store provider (the default provider), but it is not raised
by the StateServer or SQLServer state providers
Controlling When a Session Times Out
By default, ASP.NET Framework assumes that a user has left an application after 20
minutes have passed without the user requesting a page In some situations, you want to
modify the default timeout value
For example, imagine that you are creating a college admissions website and the website
includes a form that enables an applicant to enter a long essay In that situation, you
Trang 5applicants at least 1 hour to write their essays The disadvantage of increasing the Session
timeout is that more memory is consumed by your application The longer the Session
timeout, the more server memory is potentially consumed
You can specify the Session timeout in the web configuration file or you can set the
Session timeout programmatically For example, the web configuration file in Listing
28.14 changes the Session timeout value to 60 (1 hour)
LISTING 28.14 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<sessionState timeout=”60” />
</system.web>
</configuration>
You can modify the Session timeout value programmatically with the Timeout property of
the Session object For example, the following statement changes the timeout value from
the default of 20 minutes to 60 minutes
Session.Timeout = 60;
After you execute this statement, the timeout value is modified for the remainder of the
user session This is true even when the user visits other pages
Using Cookieless Session State
By default, Session state depends on cookies The ASP.NET Framework uses the
ASP.NET_SessionId cookie to identity a user across page requests so that the correct data
can be associated with the correct user If a user disables cookies in the browser, Session
state doesn’t work
If you want Session state to work even when cookies are disabled, you can take advantage
of cookieless sessions When cookieless sessions are enabled, a user’s session ID is added to
the page URL
Here’s a sample of what a page URL looks like when cookieless sessions are enabled:
http://localhost:4945/Original/(S(5pnh11553sszre45oevthxnn))/SomePage.aspx
The strange-looking code in this URL is the current user’s Session ID It is the same value
as the one you get from the Session.SessionID property
Trang 6You enable cookieless sessions by modifying the sessionState element in the web
config-uration file The sessionState element includes a cookieless attribute that accepts the
following values:
AutoDetect—The Session ID is stored in a cookie when a browser has cookies
enabled Otherwise, the cookie is added to the URL
UseCookies—The Session ID is always stored in a cookie (the default value)
UseDeviceProfile—The Session ID is stored in a cookie when a browser supports
cookies Otherwise, the cookie is added to the URL
UseUri—The Session ID is always added to the URL
When you set cookieless to the value UseDeviceProfile, ASP.NET Framework determines
whether the browser supports cookies by looking up the browser’s capabilities from a set
of files contained in the following folder:
\WINDOWS\Microsoft.NET\Framework\[version]\CONFIG\Browsers
If, according to these files, a browser supports cookies, the ASP.NET Framework uses a
cookie to store the Session ID The Framework attempts to add a cookie even when a user
has disabled cookies in the browser
When cookieless is set to the value AutoDetect, the framework checks for the existence of
the HTTP Cookie header If the Cookie header is detected, the framework stores the
Session ID in a cookie Otherwise, the framework falls back to storing the Session ID in the
page URL
The web configuration file in Listing 28.15 enables cookieless sessions by assigning the
value AutoDetect to the cookieless attribute
LISTING 28.15 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<sessionState
cookieless=”AutoDetect”
regenerateExpiredSessionId=”true” />
</system.web>
</configuration>
Trang 7NOTE
The easiest way to test cookieless sessions is to use the Mozilla Firefox browser
because this browser enables you to easily disable cookies Select the menu option
Tools, Options Select the Privacy tab and uncheck Allow Sites to Set Cookies
The configuration file in Listing 28.15 also includes a regenerateExpiredSessionId
attribute When you enable cookieless session state, you should also enable this attribute
because it can help prevent users from inadvertently sharing session state
For example, imagine that someone posts a link in a discussion forum to an ASP.NET
website that has cookieless sessions enabled The link includes the Session ID If someone
follows the link after the original session has timed out, a new Session is started
automati-cally However, if multiple people follow the link at the same time, all the people share
the same Session ID and, therefore, they share the same Session state, which is a major
security problem
On the other hand, when regenerateExpiredSessionId is enabled and a session times
out, the Session ID in the URL regenerates when a person requests the page A redirect
back to the same page is performed to change the Session ID in the URL If a link is posted
in a discussion forum, or sent to multiple users in an email, each user who follows the
link is assigned a new Session ID
When you enable cookieless sessions, you need to be careful to use relative URLs when
linking between pages in your application If you don’t use a relative URL, the Session ID
cannot be added to the URL automatically
For example, when linking to another page in your website, use a URL that looks like this
(a relative URL):
/SomeFolder/SomePage.aspx
Do not use a URL that looks like this (an absolute URL):
http://SomeSite.com/SomeFolder/SomePage.aspx
If, for some reason, you need to use an absolute URL, you can add the Session ID to the
URL by using the Response.ApplyAppPathModifier() method This method takes an
absolute URL and returns the URL with a Session ID embedded in it
Configuring a Session State Store
By default, Session state is stored in memory in the same process as the ASP.NET process
There are two significant disadvantages to storing Session state in the ASP.NET process
First, in-process Session state is fragile If your application restarts, all Session state is lost
A number of different events can cause an application restart For example, modifying the
web configuration file or errors in your application both can cause an application restart
Trang 8Second, in-process Session state is not scalable When Session state is stored in-process, it
is stored on a particular web server In other words, you can’t use in-process Session state
with a web farm
If you need to implement a more robust version of Session state, ASP.NET Framework
supplies you with a number of options You can configure ASP.NET Framework to store
Session state in an alternative location by modifying the Session state mode
You can set the Session state mode to any of the following values:
Off—Disables Session state
InProc—Stores Session state in the same process as the ASP.NET process
StateServer—Stores Session state in a Windows NT process, which is distinct from
the ASP.NET process
SQLServer—Stores Session state in a SQL Server database
Custom—Stores Session state in a custom location
By default, the Session state mode is set to the value InProc This is done for performance
reasons In-process Session state results in the best performance However, it sacrifices
robustness and scalability
When you set the Session state mode to either StateServer or SQLServer, you get
robust-ness and scalability at the price of performance Storing Session state out-of-process
results in worse performance because Session state information must be passed back and
forth over your network
Finally, you can create a custom Session state store provider by inheriting a new class
from the SessionStateStoreProviderBase class In that case, you can store Session state
any place that you want For example, you can create a Session state store provider that
stores Session state in an Oracle or FoxPro database
Configuring State Server Session State
When you enable State Server Session state, Session state information is stored in a
sepa-rate Windows NT Service The Windows NT Service can be located on the same server as
your web server, or it can be located on another server in your network
If you store Session state in the memory of a separate Windows NT Service, Session state
information survives even when your ASP.NET application doesn’t For example, if your
ASP.NET application crashes, your Session state information is not lost because it is stored
in a separate process
Furthermore, you can create a web farm when you store state information by using a
Windows NT Service You can designate one server in your network as your state server
All the web servers in your web farm can use the central state server to store Session state
Trang 9You must complete the following two steps to use State Server Session state:
1 Start the ASP.NET State Service
2 Configure your application to use the ASP.NET State Service
You can start the ASP.NET State Service by opening the Services applet located at Start,
Administrative Tools (see Figure 28.6) After you open the Services applet, double-click the
ASP.NET State Service and click Start to run the service You also should change the
Startup type of the service to the value Automatic so that the service starts automatically
every time that you reboot your machine
FIGURE 28.6 Starting the ASP.NET State service
If you want to run the ASP.NET State Service on a separate server on your network, you
must edit a Registry setting on the server that hosts the ASP.NET State Service By default,
the ASP.NET State Service does not accept remote connections To allow remote
connec-tions, execute RegEdit from a command prompt and set the following Registry key to
the value 1:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\
➥Parameters\AllowRemoteConnection
After you start the ASP.NET State Service, you need to configure your ASP.NET application
to use it The web configuration file in Listing 28.16 enables State Server Session State
Trang 10LISTING 28.16 Web.Config
<?xml version=”1.0”?>
<configuration>
<system.web>
<sessionState
mode=”StateServer”
stateConnectionString=”tcpip=localhost:42424”
stateNetworkTimeout=”10” />
<machineKey
decryption=”AES”
validation=”SHA1”
decryptionKey=”306C1FA852AB3B0115150DD8BA30821
➥CDFD125538A0C606DACA53DBB3C3E0AD2”
validationKey=”61A8E04A146AFFAB81B6AD19654F
➥99EA7370807F18F5002725DAB98B8EFD19C711337E2
➥6948E26D1D174B159973EA0BE8CC9CAA6AAF513BF84E44B2247792265” />
</system.web>
</configuration>
The web configuration file in Listing 28.16 modifies three attributes of the sessionState
element First, the mode attribute is set to the value StateServer Next, the
stateConnectionString attribute is used to specify the location of the ASP.NET State
Server In Listing 28.16, a connection is created to the local server on port 42428 Finally,
the stateNetworkTimeout attribute specifies a connection timeout in seconds
NOTE
You can configure the ASP.NET State Server to use a different port by modifying the
following Registry value:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\
➥Parameters\Port
You need to stop and restart the ASP.NET State Service with the Services applet after
making this modification
The web configuration in Listing 28.16 includes a machineKey element If you are setting
up a web farm, and you need to use the same State Server to store Session state for
multi-ple servers, you are required to specify explicit encryption and validation keys On the
other hand, you don’t need to include a machineKey element when the ASP.NET State
Server is hosted on the same machine as your ASP.NET application