Chapter 13. The HttpApplicationState Class
Developers who are new to web-based development encounter several challenges. Among the most serious is the realization that rather than a single monolithic application, web-based applications are just a series of pages. A web server is like an unusually inattentive waiter. Imagine sitting down for dinner and placing your order for drinks. When you next see the waiter, he asks you again what you would like to drink, as if he has never seen you before. Each request to the web browser is seen as a completely new request, totally unrelated to any previous request.
Several problems with the way web-based applications are structured need to be resolved:
Session data in ASP.NET can be managed in the HttpSessionState class, which will be covered in Chapter 19. Global data can be stored in the HttpApplicationState class, which is covered in this chapter.
ASP.NET creates the illusion that pages are grouped into an application. An instance of the HttpApplicationState class is created the first time any client requests a URL resource from within the virtual directory of a particular application. The HttpContext class (covered in Chapter 14) exposes a property named Application that provides access to the HttpApplicationState class for the application. The Application property and the HttpApplicationState object it returns are also available from the Page class. Since each ASP.NET page inherits from the Page class, the Application property is available to code on every page.
While this chapter covers the HttpApplicationState class, ASP.NET offers an alternative way to store information with an application global scope. The Cache class allows a developer to store data with an application scope. In addition to caching page output (a topic covered in Chapter 3), ASP.NET allows the developer to store other information within the Cache—in some ways similar to the way information can be stored in the HttpApplicationState class. There are, however, significant differences:
One significant limitation of both the Cache and the HttpApplicationState objects is that they are not shared across servers in a web farm. While classic ASP programmers will not be surprised by this, ASP.NET programmers who are familiar with the HttpSessionState object might be surprised, since in ASP.NET, session state can be shared across a server farm—either in a state server or a special SQL Server database. While having cached items available across all servers on a web farm would be convenient, the nature of what is stored in the HttpApplicationState object makes the lack of a shared data store less critical.
The implications of the difference between HttpApplicationState and the Cache are clear:
Classic ASP developers often used the Application object to store things like database connection strings. In ASP.NET, there is another alternative for storing small, possibly sensitive bits of information like connection strings. Inside the configuration files for the machine or applications, you can place values called appSettings within the <configuration> tag. For instance:
<appSettings> <add key="TestKey" value="TestValue" /> </appSettings>
Multiple add tags can be placed in the configuration file. To retrieve the value within code, you the System.Configuration.ConfigurationSettings class. Specifically, to retrieve the value saved in the TestKey key above, use the following code:
localVar = ConfigurationSettings.AppSettings("TestKey")
While you can place the appSettings section in web.config or machine.config, sensitive values are better stored in the machine.config file. machine.config is not located in a folder that is in any way mapped within the web-accessible space. Of course, this solution for storing application-level information is really only suitable for static information that does not need to change under program control as the application is running. Often, you can use AppSettings and Application state together, caching the value from AppSettings within the Application object. If a setting with the same key is contained in both the machine.config and web.config file, the value in web.config will be the value returned for the setting.
Much of HttpApplicationState will be familiar to classic ASP developers. The visible additions and changes from classic ASP are not dramatic. Most importantly, virtually all existing classic ASP code dealing with the Application object will work in ASP.NET.
When the first client requests a URL from the application, the Application object's start event is fired. This event can be handled by creating an event handler in the global.asax file (the ASP.NET equivalent of global.asa) with the following signature:
Sub Application_OnStart( ) 'Application initialization code End Sub
The Application start event is called only once within the lifetime of an application. This is where you would usually set Application variables. When the Application ends, a similar event is called with the following signature:
Sub Application_OnEnd( ) 'Application cleanup code End Sub
In the Application end event, you would dispose of any resources created in the Application start event. There are a few limitations to what you can do in the Application-level events, since the Response, Session, and Request objects are all unavailable.
The fact that the Application start event is called once within the lifetime of an application was mentioned above. However, what exactly is the lifetime of an application? Whenever the web server starts up, the first client to request a URL from an application marks the beginning of the application's lifetime. Similarly, as the web server stops, either because the underlying service is stopped or the server itself is restarted, the application's lifetime ends. Thus, can you presume that unless the web service restarts or the server itself restarts, the application will continue running? The short answer is "No."
The longer answer is that to ensure that the Application start and Application end events called are coherent (i.e., that code has not been added to Application_End that would require changes to Application_Start after it had already fired, or vice-versa), any time the global.asax is changed, the ASP.NET framework detects that the file has changed. Upon sensing the file change, the framework completes any current requests and fires the Application end event (as it existed before the change to global.asax). Once the Application end event has fired, the application restarts, flushing all application information and client state information. When the next incoming client request is received, the ASP.NET framework reparses and recompiles the global.asax file and raises the Application start event as it appears in the newly saved version of global.asax. The moral of this story is that changes to the global.asax file should be infrequent, presuming the application must be available 24/7.
One question that sometimes arises is, "Can the Application state of one application be accessed from within another application?" The short answer is "No." The longer answer is that if the other application cooperates, you can create a page in one application that can be called by making an HTTP Request from the other application. There is no support within the ASP.NET Framework to do this explicitly.
Items can be stored in the Application collection in one of four ways:
Items can be accessed in one of four ways:
Items can be removed from the Application collection in one of several ways:
Table 13-1 lists the properties, collections, and methods exposed by the HttpApplicationState class.