Pitfalls of Application Variables
Because only one instance of the Application object exists for the entire Web application, application variables can be used more liberally than session variables. However, the Application object does take up memory on the Web server, so only items that need to be stored in application scope should be entered into the Application object. Two common pitfalls should be avoided when working with application variables:
- Pitfall 1 - Do not put objects into the Application object unless vitally needed.
- Pitfall 2 - Only create application variables that are necessary. Why create unneeded application variables when they'll only waste your Web server's memory?
A common pitfall among developers is wanting to place objects in the Application. One object that is particularly alluring to put into the Application is the ADO Connection object, which is used to connect to a database. We'll discuss this object in detail during Week 3. It may seem like a good idea to create a single database connection object and have all users communicate to a database through that object. However, as with most other objects, it is always best to wait to create the object until you need it. In fact, the ADO Connection object will degrade your server's performance if put into the Application object.
Like the Session object, the Application object is easy to use, and the temptation to create a plethora of application variables is high indeed. Many developers use the Application object to store many Web site-wide constants - for example, a navigational footer common to all Web pages, or perhaps the Webmaster's email address. Although it's better to place these items in the Application object than in the Session object, they belong best in a static text file on the Web server. This text file can then be included into any ASP page that needs to display the navigation footer or the Webmaster's email address. We will discuss how to include files on Day 13.
Sometimes, however, the use of application variables is preferred to include files. If the data you need to store changes often, such as the last post to a message board, then the information should be stored in the Application object. Include files should only be used if the data is static and not susceptible to frequent change.
Although you can afford to be less prudent when creating application variables than you can be when creating session variables, you should still strive to use the minimum needed amount of such variables. Because the Application object persists in the Web server's memory, the fewer the application variables stored within it, the less drain on the Web server's performance. Therefore, the Application should remain free of objects and contain only needed application variables.
Initializing Application and Session variables
Recall that the Session and Application objects serve as warehouses for session and application variables, respectively. When the user first visits the site, a new Session warehouse is created. What is inside this warehouse by default? Initially, the warehouse is empty. Attempting to retrieve a nonexistent session variable from the users Session returns an empty string.
However, the Session and Application objects both have an event you can use to initialize the contents of your users Session and your Web site's Application. This event is called the OnStart event, and it occurs at different times for the Session and Application objects. The Session's OnStart event occurs whenever a new user comes to the site. This is when a new Session object instance is created for this particular user. In the OnStart event, you can create the session variables you plan to use and initialize them to certain values. The Application's OnStart event fires when the first Session object is instantiated - that is, when the first Session's OnStart event fires.
To create and initialize session and application variables, you need to write event handlers for the OnStart events. Listing 11.13 displays the OnStart event handler for both the Session and Application objects.
Listing 11.13 - Initializing Application and Session Variables in the OnStart Events
Listing 11.13 displays the OnStart event handlers for the Session and Application objects. The Application object's OnStart event handler begins on line 1. A single application variable, LastPost, is initialized to a blank string (line 2). The Session object's OnStart event handler begins on line 5. Line 6 creates a session variable named LogonTime that is initialized to the Web server's current date and time. Next, a session variable, Name, is created and initialized to an empty string (line 7). Line 9 creates aPi, an array, and lines 10 through 13, set the three elements of aPi. Line 13 creates the final session variable, setting it equal to aPi.
Note the syntax for creating an event handler (lines 1 and 5). First, a subroutine is created and named with the object's name, followed by an underscore, and then followed by the event name. Because the OnStart event passes in no parameters, no arguments are in the event handler definition.
Whenever these events fire, the functions in Listing 11.13 are executed. The OnStart event for the Session object occurs whenever a new visitor (one that does not already have a Session instance) arrives at the site. If your Web site experiences a lot of traffic, this event can fire hundreds, or even thousands of times an hour. The Application's OnStart event, however, fires only once, right before the first Session is created. If you restart your Web server, though, the next visit after restarting causes the Application object's OnStart event to fire.
Creating a Global.asa File
We've looked at the code to handle the OnStart event of the Session and Application objects, but we've not discussed where we should place the code shown in Listing 11.13. To handle Session and Application events, a special file needs to be created. This file must be named, precisely, Global.asa and needs to be placed in the root directory of your Web site. When a new user comes to your site and Global.asa exists, the correct event handler in Global.asa is executed.
What should Global.asa look like? Listing 11.13 showed the syntax for the OnStart event handler, but Global.asa also needs a couple extra lines to run properly. Listing 11.14 shows a complete Global.asa, incorporating the event handlers shown in Listing 11.13.
Listing 11.14 - A Complete Global.asa
Listing 11.14 shows a complete Global.asa file. For this to take effect, it needs to be placed in the Web's root directory. Note that lines 2 through 15 are identical to lines 1 through 14 in Listing 11.13. The only difference between the two listings is that Listing 11.14 contains the <SCRIPT> tag (lines 1 and 16). The <SCRIPT> tag on line 1 contains two properties, LANGUAGE and RUNAT. LANGUAGE determines what language the <SCRIPT> block will be written in. RUNAT determines whether the <SCRIPT> block will be run on the Web server, or passed to the client. We discussed the <SCRIPT> block notation for writing ASP on Day 2, "Dissecting Your First ASP Script." Line 16 contains the close of the <SCRIPT> tag, specifying that the <SCRIPT> block has ended.
|Global.asa should only contain initialization of session and application variables. In fact, all the session and application variables that you use on your Web site should be created and initialized in Global.asa.|
Both the Session and Application objects support another event, the OnEnd event. For the Session object, this event is fired when a user's Session times out, or when the Session.Abandon is called. The Application object's OnEnd event is fired when the Web server is being shut down. You can perform any cleanup maintenance in these two event handlers. For example, if you created any session variables in the OnStart event handler, you should explicitly delete those objects in the OnEnd event handler.
In the Session object's OnEnd event handler, the only built-in objects available are the Session, Application, and Server objects. In the Application object's OnEnd, only the Application and Server objects are available for use. This is understandable because the Application's OnEnd event handler isn't fired until the last Session is destroyed. Listing 11.15 shows a complete Global.asa, one that contains an OnStart and OnEnd event handler for both the Session and Application object.
Listing 11.15 - Global.asa Containing the OnEnd Event
Listing 11.15 enhances the Global.asa file by adding the OnEnd event handlers for the Session and Application objects. Listing 11.15 begins with the OnStart event handler for the Application object (line 2). In this event handler, an application variable named MyDict is created that holds an instance of the Dictionary object (line 4). On line 8, the OnEnd event for the Application object is placed. Note how the subroutine's definition is similar to that of the OnStart event handler. The only difference is that in place of OnStart, OnEnd is used instead. Line 10 explicitly frees the MyDict application variable by setting it equal to Nothing.
The Session object's OnStart event handler is coded on line 14. When a new Session is created, a session variable named MyObject is created and set equal to an instance of the My.Obj object (line 18). Placing an object in the Session, of course, could lead to performance degradation on high volume Web sites. On line 21, the OnEnd event handler for the Session object starts. Finally, on line 23, the session variable MyObject is explicitly destroyed by setting it equal to Nothing.
Note that the OnEnd event handlers are only being used to explicitly free objects. Rarely do you place anything else in the OnEnd event handlers. Because the Session object's OnEnd event handler occurs a while after the user has left your site (depending on the Session.Timeout property), you cannot display a message to them, or redirect them to another page. The OnEnd event handlers should do nothing more than simply clean up the objects created by the OnStart event handlers.
DO use Global.asa to create and initialize all your session and application variables with the OnStart event handlers. Also, Global.asa should contain the OnEnd event handlers to explicitly free any session or application variable objects.
DON'T use Global.asa to try to redirect users to other pages or to display or retrieve information.