Barry S. Stahl, MCSD
Skip Navigation LinksBarry S. Stahl, MCSD > Articles > State Mechanisms in ASP
Skip Navigation Links.

State Mechanisms in ASP

Originally Published 3/2/2001 on WebReview.com

Currently, there are four major methodologies that are used to store data for web applications in Microsoft’s Active Server Pages. These methods have been discussed individually in the past, but there seems to be a need for an overview of those methods that includes explanations of when it may be appropriate to use them. In this article, I will give a brief introduction to maintaining state in ASP and will present each of the four, examining the benefits and costs of each in the hopes of assisting you in determining what methodology best suits your application.

As you know, HTTP, the protocol on which the Web transports its data, is stateless. That means that if you want a web application to remember some information from one request (page load) to the next, the web developer has to implement some type of state mechanism to store the data. There are four methods that are typically used to store this data. The information can be stored on the client machine in hidden fields or in cookies, on the server using the ASP session object, or on the server using a custom method such as in a database. No matter which method you choose, at least one data item will have to be stored on the client, probably in the form of a cookie, in order to identify that user. We’ll look at each of these methods in some detail.

Client Side State Mechanisms

The most straightforward way of maintaining state using ASP (or pure HTML for that matter) is to store the values of the variables you wish to save in hidden form fields. This data can be sent to the server using either the HTTP Get or Post method. If the Get method is used, all the data will appear on the URL line in the Address bar at the top of the browser. If the Post method is used, the data will be hidden from view unless the user selects the “view source” option of their browser. Either way, the data is very easy to modify at the client side. This method is implemented in ASP by using an HTML input field to send the data to the browser, and the ASP Request object to read the values back into the server. For example: <input type=”hidden” name=”UserName” value=”Joe User”> stores the value “Joe User” in the HTML field named “UserName”. Then, the ASP statement: <% sUserName = Request.QueryString(“UserName”) %> will read this value back into your ASP application. While this method of storing state information is fairly easy to understand, it has some severe limitations. First of all, it requires that every page that the user hits contain a form that maintains this state information. If the user were to type in a URL into the address field on his or her own, click on a link that is not part of the form that holds the data, close his or her browser, or click on a favorite, then all of the information will be lost. Because of these limitations, and others discussed below in reference to using cookies, I do not recommend using this methodology. Instead, if you wish to store data on the client-side, take a look at the next method of maintaining state, the HTTP Cookie.

HTML Cookies are a somewhat more reliable method of maintaining state. A cookie is a named piece of data stored on the client machine by the browser, and sent to the server in the header of any page request to the same server that originally sent the cookie to the client. While this all may sound complicated, Active Server Pages makes using cookies to store data on the client-side easy by providing properties of the request and response objects that handle reading and writing cookies. For example, the ASP statement:

<% Response.Cookies(“Username”).Value = “Joe User” %>

Sets the value of the cookie Username to “Joe User” and stores that information in the client’s browser. Then, at the next request, we can execute the following statement:

<% sUserName = Request.Cookies(“Username”).value %>

This retrieves the value stored in the Username cookie from the browser. Using cookies is virtually as straightforward a way of storing state as the HTML form since each item is simply stored in the users browser under the domain name from the Address box of the browser. All cookies from that domain will be sent with the request and can be read by the server-side ASP code each time the domain that supplied the cookie is accessed by that particular browser. However, this information is far safer since the user can go to another site or close his or her browser and the information will still be available. This methodology is often preferred to server-side methods when only a few bytes of information need to be maintained since it does not require creating any type of data store on the server-side. Also, may purists believe that client data belongs to the client and therefore should be stored on the client computer.

Disadvantages to using cookies, like the HTML form method, include the fact that all of the data stored will have to be sent over the wire each time a page is loaded from the issuing domain. This can significantly impact loading speed especially if large amounts of data are being sent across a small pipe. In addition, data stored in cookies is not secure. This data can be modified or even deleted at the client side, and unless the connection with the client is encrypted, is sent over the Internet in plain text. Applications that require large amounts of data to be stored, or that need to maintain the state of data that should not be able to be modified by the client are not good candidates for using client-side mechanisms by themselves. One variation of this method that can reduce some of these downfalls involves storing all information in one encoded cookie on the client. This implementation can reduce bandwidth usage somewhat if a good compression algorithm is used and can also increase security slightly over the standard cookie implementation. This variation is the implementation Microsoft has chosen as a standard for their .NET initiative.

Server-Side State Mechanisms

The first of the server-side methodologies involves the use of the Microsoft Server-Side state objects native to ASP. These are the Application object used for maintaining application level state in an ASP app (all users of the app share this data) and the Session object used for maintaining session level (per-user) data. As with the cookie method, ASP handles the details of implementation for you, allowing the developer to store and retrieve data easily with statements such as: <% Session(“Username”).value = “Joe User” %> And <% sUsername =Session(“Username”).value %>

Application level data can be stored and retrieved just as easily by replacing the Session object with the Application object as in the following example: <% Application(‘UserCount”).value = Application(“Usercount”).value + 1 %> And <% lUserCount = Application(“UserCount”).value %>

The biggest advantage to using this method comes when storing medium quantities of scalar data. Since information stored in these objects is kept in the memory of the server, storage and retrieval can be quite fast and can scale reasonably well to handle higher volumes of traffic. Also, since the vast majority of the data is stored on the server, bandwidth requirements can be significantly lower than the client-side methods discussed earlier. However, there can be major drawbacks to using this method for high-traffic websites. First off, when information is stored in the memory of the web-server, that data is not available to other servers, rendering the use of server-farms impossible with this technology today. If it is likely that your application will be moved to a server-farm in the future, you may wish to avoid using this memory-resident methodology (Microsoft has promised a solution to this particular problem in the next release of ASP called ASP+). Also, since this data is never persisted to the file system, after the session times-out (for session level data) or the Application ends (for Application level data), the information is lost. If a customer comes back after a month, it is very likely that everything they did in their previous visit will no-longer be available to the application. In addition, a server crash would cause the loss of Session/Application data.

Another failing of this system is in its ability to store non-free-threaded objects such as those created with Visual Basic 6. Microsoft’s Internet Information Server (IIS) allocates twenty threads by default to a pool that can be used for objects stored in Session and Application state. If these objects are not free-threaded, they can only be activated on the thread that they were created on. Applications that get more than 20 concurrent users or store a number of objects in this thread-pool run the risk of bottlenecks when accessing objects that are limited in what thread they can run on. Simply put, storing objects that are Single or Apartment threaded in the Session or Application objects can cause significant performance problems for sites that receive more than twenty concurrent users. Another potential limiting factor of this methodology is that since all of the data is stored in the memory of the server, large quantities of data for a large number of users can end up utilizing a majority of the server’s available memory. I highly recommend running performance tests using Microsoft’s Web Application Stress Tool (a free download) to see what kind of impact on memory and CPU usage this methodology has on your particular server and application. Please note that this built-in method of storing data server-side still requires that a key to the server data be stored on the client. In this case the ASPSession cookie is used automatically by ASP to identify the user and store/retrieve that user’s data.

For those applications that get a large number of concurrent users and need to store object data or whose data storage requirements exceed the memory constraints of the web server, a custom solution is required. These implementations of state mechanisms may store the information in a database, or in the file system of the server such as in an XML file. Clearly such a solution is more costly than the other two methods, both in development and maintenance costs and may require a higher-end server or even an additional database server to implement. However, these custom solutions can implement the ability to store non-scalar data such as VB objects without running into thread-pooling issues, and can be implemented such that a server-farm is still useable by the application. This methodology is also best when the data needs to be stored for long periods of time (typically anything over 20-minutes, the default length of an ASP session). For example, data stored in a database can be kept there permanently, or deleted at the application’s discretion perhaps by a cleanup program that deletes all data that has not been accessed within the last year. Most solutions of this type will involve the creation of custom objects that replace the Application and/or Session objects of ASP, however, the state could be maintained simply by making database or file-system calls from within ASP at some cost of performance. As with the Application/Session method, some form of client-side data will probably be required to act as an index to the data stored on the server. In this case, the developer will be responsible for setting up and maintaining this information on the client.

In summary, the key to knowing which type of state method is best for your application, is to know your app. Sites requiring small amounts of data that do not need to be secured and where the data may be traveling over a large pipe can use a client-side implementation, most likely the pure-cookie methodology. Applications that need to store their data on the server-side to avoid security risks, but do not require non-scalar data, large quantities of data, or long-term storage of that data are good candidates for the built-in ASP state mechanism consisting of the Application and Session objects. Finally, high-volume sites requiring large quantities of secure or non-scalar data that needs to be stored over a long period should use a custom solution. Whatever implementation you choose, be certain to performance-test your application to be sure that it meets your needs both now and in the future.