As Web applications become more powerful, they become more complex. Fortunately, with the continual flow of new technologies and tools from Microsoft, developers and IIS administrators can build and administer applications they wouldn't have considered just a few years ago.
The global.asa file in an Active Server Pages (ASP) application is the foundation of these complex Web applications. In global.asa, software developers can design and build the basis for powerful, scalable, and high-performance Web applications. Global.asa is also a place where developers frequently make disastrous mistakes—mistakes that bring IIS servers down. To effectively administer and troubleshoot the ASP applications running on your IIS machines, you need to understand the global.asa file.
The Rules, Structure, and Function of Global.asa
Global.asa is an editable text-based file that consists entirely of server-side script. Global.asa can contain any script-compliant language (VBScript is the most common language), but it contains no HTML that renders content to a browser. If you edit the file—or even if you save the file without making any changes to it—IIS recompiles it. For more information about how global.asa executes, see the sidebar "The Global.asa Execution Process," page 2. Global.asa has two important roles.
Storing event script code. Global.asa stores event script code that the Web application automatically executes when the appropriate conditions are met. For example, the Session_OnStart event fires each time a new user accesses a resource on a Web site. Session_OnStart establishes session state, which is a temporary store for user session information. When the session ends (or times out), the Session_OnEnd event fires. Session_OnStart might include code that reads a cookie containing explicit and implicit user preferences for a Web site. (Explicit preferences are those preferences that the user specifically defines, such as favorite colors and links. Implicit user preferences are those preferences that the Web application automatically gathers, such as last product viewed and most frequently visited page.) The Session_OnEnd event might then include event code that automatically updates the implicit user preferences in the user's cookie. The Session_OnStart and Session_OnEnd events assume that the Web site supports session state. (To enable session state on your Web site, see the sidebar "Enabling Session State,"page 2.)
Housing globally used objects. Global.asa facilitates defining items (i.e., objects and variables stored in memory) that become globally available to the Web application. For example, later in this article you'll see an application-level variable called MSCSEnv that has the value PRODUCTION. This value means that anywhere in the Web site, you can use logic in the form
Do something that you would
do only in a production environment
Do something that you would do only in a development environment
A global.asa file isn't required for all Web applications. Static Web sites, for example, don't need the functionality that global.asa provides. But if you use a global.asa file in your application, you can have only one per application, and you must name the file global.asa. Additionally, global.asa must reside in the Web application's root directory or the file won't function.
Global.asa files include two types of global variables: those with application scope and those with session scope. A variable with application scope is available to the entire Web application. You can change the value of an application-level variable, but if you do so while the Web application is running, IIS automatically stops all processing while IIS updates the cache.
At a client site recently, I saw an interesting Web architecture in which the Web application read a list of products from a database, then assigned that information to an application-level variant-array variable in the Application_OnStart event. Then, when any page in the site needed to display the list of products, the Web server didn't need to go back to the database to grab the list because it was available. The application's performance was spectacular. Unfortunately, this strategy works only for a site with a static list of products. A second client employed a similar architecture in a site in which products changed daily. When users on the site requested the product list, they had to wait 30 to 45 seconds while the Web server reread the database and updated the value of the application-level variable.
A variable with session scope is a global variable that's available to the entire Web application but specific to a user's session. Session scope facilitates user-level assignment of variables, such as favorite color.
Session-state management is one of the most difficult parts of Web programming. Unlike Win32 programming, in which you take for granted that when you define a global variable you can use that variable throughout the application's programs, Web programming doesn't guarantee that a variable's life will continue from one Web-application page to the next. A variable that you assign in one ASP page won't be available for use in a subsequent page.
When Microsoft introduced session-level variables to ASP, they seemed like a simple way to assign variables and keep their information available as the user moved from page to page. However, session-level variables don't scale; in fact, they cripple an IIS Web server as more users access a site. As a rule of thumb, never use session-level variables on public sites; on intranet and extranet sites, use these variables only when you can predict and control loads.
Now, let's take a look at a portion of a very complex global.asa file—the global.asa file for Microsoft Commerce Server 2000's retail solution site. (You can install this sample site when you install Commerce Server on your machine.) This global.asa file and all its include (.inc) files comprise more than 5000 lines of code. Listing 1 shows an excerpt from the Commerce Server global.asa file. You can download this global.asa file excerpt from the Code Library on the Windows Web Solutions Web site (http://www.windowswebsolutions.com).
The code at callout A in Listing 1 is a good example of an important global.asa function: type library definitions. A type library is a file that contains information about objects and types that a COM component supports. You define type libraries in the global.asa file so that in the ASP code that makes up a Web site's pages, you can use the constants declared in the COM component. Type library definitions (in fact, all metadata declarations) can appear anywhere in the global.asa file, but placing them first is a good programming practice because they're easier to find, read, and maintain.
The next statement defines the scripting language in which the global.asa file is written—in this case, server-side VBScript. The Option Explicit statement in the next line, although unnecessary in ASP code, forces you to declare all variables before you use them.
The code at callout B defines, in the form of constants, the properties of text boxes used in the Web site. Constants are variables to which you assign a value that doesn't change. Using constants saves memory and organizes variable definitions. Notice the L_ at the beginning of each constant name. This letter stands for localizable. This naming convention makes using automated tools to convert ASP sites from English, for example, into other spoken languages easy.
The code at callout C declares the global variables that the script will eventually define as application level. In the code at callout D, notice the environment variable MSCSEnv (Microsoft Commerce Server Environment), which I mentioned earlier. The Application_OnStart event defines this variable as an application-level variable so that it will be available in every page in the Web site and sets its value to PRODUCTION. Then, the script calls the Main() function. Main is declared in the global_main_lib.asp include file that accompanies the Commerce Server global.asa file. Defining include files makes reading global.asa files much easier. You can imagine how confusing and intimidating a 5000-line global.asa file would be.
Notice that this global.asa file doesn't call the Application_OnEnd event—everything in the Web application automatically shuts down when the application shuts down, so you don't need to specifically call the event. Also, like most ASP sites, the Commerce Server retail solution site doesn't use session state because it doesn't scale. By design, the Session_OnStart and Session_OnEnd events aren't declared. (Commerce Server uses a sophisticated state-management system built on Microsoft SQL Server and COM. This system is declared in the global.asa file's include files.)
Peeking Under the Covers
Knowing what goes on under the covers of the Web applications running on your IIS servers is important for good IIS administration and can help you understand resource consumption. Understanding the global.asa file is a great place to start when you're trying to understand the inner workings of a Web application. This knowledge will also help you diagnose problems if your IIS servers degrade under heavy loads.
Next month, I'll begin a three-part series about optimizing IIS for ASP.NET applications. The first article will explore ASP.NET's web.config file. Web.config is the Microsoft .NET equivalent of the global.asa file, but it's more controllable and, therefore, much more powerful.