Using the Session Object
The ViewState information is great for maintaining state across postbacks on a single page, but as you develop Web applications in .NET, you will find that there is a definite need to keep track of data from one page to another, not just on a single page. That's when you need a Session object.
Each time a new user comes into your site, IIS creates a new Session object. IIS automatically assigns a unique number to this session and places it into the Session object's SessionID property. You can use this SessionID to uniquely identify a particular user and create your own session variables to hold state as long as that user's session is active. IIS sends the value of the SessionID property to the browser as a dynamic cookie; each time the browser navigates to any page on the site, this cookie is sent to the server via the HTTP header.
In order to make use of the Session object, your users must accept cookies. Although most users don't turn off this capability in their browsers, some do. You'll see, later in this chapter, how you can eliminate cookies when using Session variables.
The Session object for a particular user does not live indefinitely. The ID only lives until one of the following conditions becomes true:
Your code calls the Session.Abandon method.
The Session object times out. The default timeout value is 20 minutes; therefore, if the user doesn't submit a request back to the site in that time, the Session object will be released. You can change this timeout value.
The IIS Service shuts down.
Users perceive that their sessions "die" when they close their browsers. This isn't actually the case. When a user closes his browser, all that's lost is the memory cookie that provided the link to the session on the server.
You can create your own session variables and assign values to these variables using code like this:
Session("Email") = "JohnDoe@yahoo.com"
This code creates a new session variable, named Email, which is unique for this user. Once you have created session variables, the values stay around until you explicitly set them equal to Nothing or until the session is destroyed, as explained in the previous section.
To retrieve the value of a session variable, use code like this:
txtPassword.Text = Session("Email").ToString()
The value returned when you retrieve a session variable is an Object type you'll need to convert the value as required by your application, as in the previous code example.
Issues with Session Objects
You'll need to keep in mind several issues when you're using the Session object to maintain your application's state. Here are a few of these issues:
Memory on the server is limited. Each session variable you create consumes memory on the server. Although the memory needed for one variable may not seem like much, when you multiply all the data in all your session variables by the number of users that might hit your site at one time, your session variables could be eating up quite a large amount of memory. This memory does not get released until the session is destroyed.
You'll need some security. Once a session begins, the user works with the same SessionID value until the session times out. If a hacker is able to retrieve this value, he could potentially take over the user's session. If you were storing credit card information into a session variable, it's possible that the hacker could see this information, thus causing a security leak. Although this is unlikely, it isn't impossible. To get around this problem, you might wish to employ Secure Sockets Layer (SSL) when working with sensitive information.
Session variables don't scale. A Web farm is a group of Web servers working together to service a particular Web site. Each time the user hits a page on your Web site, an IP router determines which machine is not being used too heavily and routes the request for the page to that machine. If the user is routed to a different machine than the one on which the Session object was created, the new server has no way to retrieve that state, and all that user's data is lost.
To alleviate the problem of different machines serving different pages, you can set values in the application's Web.Config file that specify the name of the machine that stores all session variables. This way, you can dedicate one machine that will do nothing but manage session variables for your site.
Although this helps with the problem of a Web farm, it introduces problems of its own. For example, this "session state" machine is one more machine that you need to keep up and running 24 hours a day. You might also need some redundancy for this machine to provide continuity while you perform maintenance tasks. In addition, the one main machine could cause performance problems, as one machine could be a bottleneck when many machines have to cross the network to get at the data. We'll discuss Web.Config settings in more detail later in the chapter.
Not all users accept memory cookies. If you have users who will not accept memory cookies in their browsers, you need to set a specific configuration option in .NET to make the session variables work correctly. In the past, memory cookies were required on the client browser to make Active Server Pages hold state. The .NET Framework can preserve session state without memory cookies. See the section "Cookieless Sessions" later in this chapter, for information on setting this up.
Turning Off Cookies Page by Page
Whenever an ASPX page is hit, the .NET runtime will, by default, attempt to generate a cookie and send it to the browser. If you know that a page will not use any session state, you can set the EnableSessionState page directive to False to turn off this automatic generation on a page-by-page basis. At the top of every ASPX page, you will find a page directive that looks like the following:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="SessionTestError.vb" Inherits="StateMgmt.SessionTestError" EnableSessionState="False" %>
If you add the EnableSessionState directive, no cookie will be generated for this page.
If you attempt to use a Session object on a page that has the EnableSessionState page directive set to False, you will receive a runtime error.