Home > Articles > Programming > ASP .NET

  • Print
  • + Share This
This chapter is from the book

State in ASP.NET Applications

Preserving state across HTTP requests is a major problem in Web programming, and ASP.NET provides several facilities that are convenient to use. There are two main types of state to be preserved.

  • Application state is global information that is shared across all users of a Web application.

  • Session state is used to store data for a particular user across multiple requests to a Web application.

Shared Data Members

Shared data members of a class are shared across all instances of a class. Hence shared data members can be used to hold application state.

In our case study the class Global has a single shared member acmedat of the class Acme.

Thus the broker and custs objects within Acme will hold shared data that is the same for all users of the application. Each user will see the same list of hotels. You can view the source code for the Acme class in the AcmeLib project.

Public Class Acme 
      Implements IAcmeUser, IAcmeAdmin 

      Public broker As HotelBroker
      Private custs As Customers 
      Private users As ArrayList 
      Private currUser As User 

If you like, you may perform a small experiment at this stage. The directory HotelAdmin contains a special version of the Acme Web site that makes available the hotel administration interface IHotelAdmin to the special user with user ID of "admin". When this privileged user logins, a special home page will be displayed that provides a link to "Administer Hotels," as illustrated in Figure 14–31.

Figure 14-31Figure 14-31 Home page of the Acme Web site tailored for administrators.

Run this Web application, either from the "Hotel Admin" link on the example programs home page or else via the URL http://localhost/ Chap14/HotelAdmin/Main.aspx. Log in as "admin" and follow the link to "Administer Hotels." You will be brought to a page showing a list of all the hotels. Select the first hotel (Dixie) on the list and click the Delete Selected Hotel button and then the Refresh button. You will now see an updated list of hotels, as shown in Figure 14–32.

Figure 14-32Figure 14-32 Hotel administration page after deleting the hotel Dixie.

If your Web server is on a network, you can now try running the same Web application from a different client. Use the URL

http://<server-name>/Chap14/HotelAdmin/Main.aspx 

where <server-name> is the name of your server machine.6 Again log in as "admin" and go to the "Hotel Admin" page. You should see the same list of hotels seen by the other client, with hotel Dixie not on the list.7 You can also experiment with different browser sessions on the same machine, adding and deleting hotels, and using the Refresh button.

Application Object

You can store global application information in the built-in Application object, an instance of the class HttpApplicationState. You can conveniently access this object through the Application property of the Page class. The HttpApplicationState class provides a key-value dictionary that you can use for storing both objects and scalar values.

For example, as an alternative to using the class Global with the shared member acmedat that we previously used, we could instead use the Application object. We make up a string name for the key—for example, "Hotel-State." In Global.asax we can then instantiate an Acme object and store it in the Application object using the following code.

Sub Application_Start(ByVal sender As Object, _
  ByVal e As EventArgs) 
       Application("HotelState") = New Acme() 
End Sub 

You can then retrieve the Acme object associated with "HotelState" by using the index expression on the right-hand side and casting to Acme, as illustrated in the code,

Dim acmedat As Acme = _ 
      CType(Application("HotelState"), Acme) 
Dim name As String = acmedat.CurrentUserInfo.FirstName 

As a little exercise in employing this technique, you may wish to modify Step 2 of AcmeWeb to use the Application object in place of a shared data member. The solution to this exercise can be found in the directory Applica-tionObject.8

Session Object

You can store session information for individual users in the built-in Session object, an instance of the class HttpSessionState. You can conveniently access this object through the Session property of the Page class. The HttpSessionState class provides a key-value dictionary that you can use for storing both objects and scalar values, in exactly the same manner employed by HttpApplicationState.

Our AcmeWeb case study provides an example of the use of a session variable UserId for storing a string representing the user ID. The session variable is created and initialized in Global.asax.

Sub Session_Start(ByVal sender As Object, _
  ByVal e As EventArgs)
       ' Fires when the session is started 
       Session("UserId") = "" 
End Sub 

We use this session variable in the Page_Load event of our home page Main.aspx to detect whether we have a returning user or a new user. A new user is redirected to the login page. (Note that "returning" means coming back to the home page during the same session.)

Private Sub Page_Load(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles MyBase.Load
       'Put user code to initialize the page here 
       Dim userid As String = CStr(Session("UserId")) 
       If userid = "" Then 
           Response.Redirect("Login.aspx")
       End If
       If Not IsPostBack Then
          Dim name As String = _ 
          Global.acmedat.CurrentUserInfo.FirstName
          lblUserName.Text = "Welcome, " & name
          lblLogin.Text = "(If you are not " & name & _
            ", please login)"
       End If 
End Sub 

There are some interesting issues in the implementation of session variables.

  • Typically, cookies are used to identify which requests belong to a particular session. What if the browser does not support cookies, or the user has disabled cookies?

  • There is overhead in maintaining session state for many users. Will session state "expire" after a certain time period?

  • A common scenario in high-performance Web sites is to use a server farm. How can your application access its data if a second request for a page is serviced on a different machine from that on which the first request was serviced?

SESSION STATE AND COOKIES

Although by default ASP.NET uses cookies to identify which requests belong to a particular session, it is easy to configure ASP.NET to run cookieless. In this mode the Session ID, normally stored within a cookie, is instead embedded within the URL. We will discuss cookieless configuration in the next section.

SESSION STATE TIMEOUT

By default session state times out after 20 minutes. This means that if a given user is idle for that period of time, the session is torn down; a request from the client will now be treated as a request from a new user, and a new session will be created. Again, it is easy to configure the timeout period, as we will discuss in the section on Configuration.

SESSION STATE STORE

ASP.NET cleanly solves the Web farm problem, and many other issues, through a session state model that separates storage from the application's use of the stored information. Thus different storage scenarios can be implemented without affecting application code. The .NET state server does not maintain "live" objects across requests. Instead, at the end of each Web request, all objects in the Session collection are serialized to the session state store. When the same client returns to the page, the session objects are dese-rialized.

By default, the session state store is an in-memory cache. It can be configured to be memory on a specific machine, or to be stored in an SQL Server database. In these cases the data is not tied to a specific server, and so session data can be safely used with Web farms.

  • + Share This
  • 🔖 Save To Your Account