BUY THIS BOOK
Add to Cart

Print Book $29.95


Safari Books Online

What is this?

Add to UK Cart

Print Book £20.95

What is this?

Looking to Reprint this content?


ASP in a Nutshell
ASP in a Nutshell, Second Edition A Desktop Quick Reference

By A. Keyton Weissinger
Price: $29.95 USD
£20.95 GBP

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Active Server Pages:An Introduction
ASP is a technology that allows you to dynamically generate browser-neutral content using server-side scripting. The code for this scripting can be written in any of several languages and is embedded in special tags inside the otherwise-normal HTML code making up a page of content. This heterogeneous scripting/content page is interpreted by the web server only upon the client's request for the content.
To understand the evolution of ASP and its current capabilities, it helps to quickly review the history of web-based content and applications.
In the early days of the World Wide Web, all information served to the client's browser was static. In other words, the content for page A served to client 1 was exactly the same as the content for page A served to client 2. The web server did not dynamically generate any part of the site's contents but simply served requests for static HTML pages loaded from the web server's file system and sent to the requesting client. There was no interactivity between the user and the server. The browser requested information, and the server sent it.
Although the static Internet quickly evolved to include graphics and sounds, the Web was still static, with little interactivity and very little functionality beyond that provided by simple hyperlinking.
Figure 1.1 illustrates the user's request and the web server's corresponding response for static (HTML, for example) web content.
Figure 1.1: Static web content: request and delivery
One of the first extensions of the static internet was the creation of the Common Gateway Interface. The Common Gateway Interface, or CGI, provides a mechanism by which a web browser can communicate a request for the execution of an application on the web server. The result of this application is converted/formatted into a browser-readable (HTML) form and sent to the requesting browser.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Static Internet
In the early days of the World Wide Web, all information served to the client's browser was static. In other words, the content for page A served to client 1 was exactly the same as the content for page A served to client 2. The web server did not dynamically generate any part of the site's contents but simply served requests for static HTML pages loaded from the web server's file system and sent to the requesting client. There was no interactivity between the user and the server. The browser requested information, and the server sent it.
Although the static Internet quickly evolved to include graphics and sounds, the Web was still static, with little interactivity and very little functionality beyond that provided by simple hyperlinking.
Figure 1.1 illustrates the user's request and the web server's corresponding response for static (HTML, for example) web content.
Figure 1.1: Static web content: request and delivery
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Dynamic Internet Part I: CGI Applications
One of the first extensions of the static internet was the creation of the Common Gateway Interface. The Common Gateway Interface, or CGI, provides a mechanism by which a web browser can communicate a request for the execution of an application on the web server. The result of this application is converted/formatted into a browser-readable (HTML) form and sent to the requesting browser.
CGI applications raised the bar on what was expected from a web site and transitioned the World Wide Web from an easy way to share information to a viable platform for information processing. The response to this evolution of the Web was rapidly accelerated growth and the beginning of the business world's interest in the Internet.
Part of this growth was the creation of several client-side scripting solutions that enabled the client's machine to take on part of the processing tasks. Chief among these client-side solutions are Netscape's JavaScript and Microsoft's VBScript.
During this huge growth in Internet-based technologies, Microsoft released its Internet Information Server. Touted as being easy to use, scalable, portable, secure, and extensible, it is also free and closely integrated with Microsoft's Windows NT and Windows 2000 operating systems. It quickly became very popular.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Dynamic Internet Part II: ISAPI
In addition to supporting the CGI specification, Microsoft introduced an alternative to CGI, the Internet Server Application Programming Interface (or ISAPI). ISAPI addresses one of the most limiting features of CGI applications.
Each time a client requests the execution of a CGI application, the web server executes a separate instance of the application, sends in the user's requesting information, and serves the results of the CGI application's processing to the client. The problem with this approach is that a separate CGI application is loaded for each request. This can be quite a drain on the server's resources if there are many requests for the CGI application.
ISAPI alleviates this problem by relying on dynamic link libraries (DLLs). Each ISAPI application is in the form of a single DLL that is loaded into the same memory space as the web server upon the first request for the application. Once in memory, the DLL stays in memory, answering user requests until it is explicitly released from memory. This increased efficiency in memory usage comes at a cost. All ISAPI DLLs must be thread-safe so that multiple threads can be instantiated into the DLL without causing problems with the application's function.
ISAPI applications are normally faster than their equivalent CGI applications because the web server does not have to instantiate a new application every time a request is made. Once the ISAPI application DLL is loaded into memory, it stays in memory. The web server does not need to load it again.
In addition to ISAPI applications, ISAPI allows for the development of ISAPI filters. An ISAPI filter is a custom DLL that is in the same memory space as the web server and is called by the web server in response to every HTTP request. In this way, the ISAPI filter changes the manner in which the web server itself behaves. The ISAPI filter then instructs the web server how to handle the request. ISAPI filters thus allow you to customize your web server's response to specific types of user requests. To state the difference between ISAPI filters and ISAPI applications (and CGI applications) more clearly, ISAPI filters offer three types of functionality that set them apart from ISAPI (or CGI) applications:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Active Server Pages and Active Server Pages 2.0
Late in the life of Internet Information Server 2.0, Microsoft began public beta testing of a technology whose code name was Denali. This technology is now known as Active Server Pages and is a very important aspect of Microsoft's Internet Information Server strategy.
This ASP technology is encapsulated in a single, small (~300K) DLL called ASP.DLL. This DLL is an ISAPI filter that resides in the same memory space as Internet Information Server. (For more about how IIS is configured to use ISAPI filters, see Appendix C.) Whenever a user requests a file whose file extension is .ASP, the ASP ISAPI filter handles the interpretation. ASP then loads any required scripting language interpreter DLLs into memory, executes any server-side code found in the Active Server Page, and passes the resulting HTML to the web server, which then sends it to the requesting browser. To reiterate this point, the output of ASP code that runs on the server is HTML (or HTML along with client-side script), which is inserted into the HTML text stream sent to the client. Figure 1.2 illustrates this process.
Figure 1.2: Dynamically generated web content: request and delivery
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
ASP: A Demonstration
The actual interpretation of the web page by the ASP.DLL ISAPI filter is best explained by example. Example 1.1 shows a simple active server page, Sample.ASP. In this example, three pieces of server-side code, indicated in boldface, when executed on the server, create HTML that is sent to the client. This is a quick introduction. Don't worry if you don't understand exactly what is going on in this example; the details will be explained in Chapter 2.
Example 1.1. Sample.ASP, an Example of Processing Server-Side Script
                  <%@ LANGUAGE="VBSCRIPT" %>

<HTML>
<HEAD>
<TITLE>Sample ASP</TITLE>
</HEAD>
<BODY>

Good afternoon.<BR> 
Welcome to the sample. It is now approximately 
<%=Time( )%> at the server. Here are a couple of
demonstrations:<BR><BR><BR>

Some simple text formatting done using HTML:<BR>
<FONT SIZE = 1>Hello Size 1</FONT><BR>
<FONT SIZE = 2>Hello Size 2</FONT><BR>
<FONT SIZE = 3>Hello Size 3</FONT><BR>
<FONT SIZE = 4>Hello Size 4</FONT><BR>
<FONT SIZE = 5>Hello Size 5</FONT><BR>
<BR>
The same text formatting using server-side code:<BR>
<%
For intCounter = 1 to 5
%>
<FONT SIZE = <%=intCounter%>>
Hello Size <%=intCounter%></FONT><BR>
<%
Next
%>
<BR>
</BODY>
</HTML>
When the client receives the HTML result from the ASP script's execution, it resembles Figure 1.3.
Figure 1.3: Client-side view of Sample.ASP
If you were to view the HTML source behind this HTML, you would see the output in Example 1.2.
Example 1.2. Sample.HTM, the Output of Sample.ASP
<HTML>
<HEAD>
<TITLE>Sample ASP</TITLE>
</HEAD>
<BODY>

Good afternoon.<BR> 
Welcome to the sample. It is now approximately 
9:28:47 at the server. Here are a couple of
demonstrations:<BR><BR><BR>

Some simple text formatting done using HTML:<BR>
<FONT SIZE = 1>Hello Size 1</FONT><BR>
<FONT SIZE = 2>Hello Size 2</FONT><BR>
<FONT SIZE = 3>Hello Size 3</FONT><BR>
<FONT SIZE = 4>Hello Size 4</FONT><BR>
<FONT SIZE = 5>Hello Size 5</FONT><BR>
<BR>

The same text formatting using server-side code:<BR>
<FONT SIZE = 1>Hello Size 1</FONT><BR>
<FONT SIZE = 2>Hello Size 2</FONT><BR>
<FONT SIZE = 3>Hello Size 3</FONT><BR>
<FONT SIZE = 4>Hello Size 4</FONT><BR>
<FONT SIZE = 5>Hello Size 5</FONT><BR>
<BR>

</BODY>
</HTML>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The ASP Object Model
ASP encapsulates the properties and methods of the following seven built-in objects:
  • Application
  • ASPError
  • ObjectContext
  • Request
  • Response
  • Server
  • Session
These objects are part of the ASP.DLL and are always available to your ASP applications.
The Application object represents your ASP application itself. This object is universal to all users attached to an application, and there is only one Application object for all users. The Application object has two events, Application_OnStart and Application_OnEnd, that fire when the first user requests a page from your application and when the administrator explicitly unloads the application using the Microsoft Management Console (see Chapter 4), respectively. The OnStart event can be used to initialize information needed for every aspect of the application. The OnEnd event can be used to do any custom cleanup work after the end of your application. You can store any variable type (with some limitations—see Chapter 3) with application-level scope. These variables hold the same value for every user of the site. See Chapter 4 for more information on the Application object.
In this book, an ASP application is a group of scripts and HTML content files that together form some function.
Added in Active Server Pages 3.0, the ASPError object allows developers to access properties that characterize the last error that occurred in the currently executing script. It is only accessible through the Server object's GetLastError method and its properties are all read-only. The addition of the ASPError object is an important one in Active Server Pages 3.0 and significantly improves the handling of errors in Active Server Page scripts. See Chapter 5, and Chapter 9, for more information.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Active Server Pages:Server-Side Scripting
Chapter 1, provided a brief introduction to Active Server Pages and how they can be used to dynamically create HTML content. In this chapter, you will learn more about what's going on behind the scenes. First we'll review scripting, scripting hosts, and scripting languages. You will learn about how Active Server Pages (the actual ASP.DLL) work to interpret your server-side code to create HTML and how IIS then inserts that dynamically created HTML into the HTML stream.
The Hypertext Markup Language, or HTML, provides for very detailed formatting of static textual content. This content can contain images, tables, and carefully formatted text and hyperlinks, making for a very powerful medium through which to present information. However, aside from the very low-level interactivity of hyperlinks and their ability to move the user from one page to another in a stream of information flowing from one page to another, HTML by itself allows for no true interactivity. HTML does not allow the web page to react to user input in any way beyond navigating to another page. HTML is an excellent way to allow for the presentation of information but does not allow for the interactivity required to transform web pages from an information medium to a dynamic web application solution.
Netscape Communications, along with Sun Microsystems, created a solution called LiveScript that allowed for the inclusion of limited programming instructions that reside in web pages viewed using the Netscape Navigator browser on the client machine. This programming language was limited in its ability to interact with the user's machine outside the browser and slowly over an evolving process was made safe and secure. You could not use LiveScript programming instructions on the client machine to undermine the security innate to the Netscape Navigator browser. LiveScript, in accordance with the marketing frenzy surrounding Java, was quickly renamed to JavaScript. Unfortunately, this renaming has led, erroneously, to its being thought of by many as a subset of the powerful Java language, although only its syntax is similar to that of Java.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Client-Side Scripting
The Hypertext Markup Language, or HTML, provides for very detailed formatting of static textual content. This content can contain images, tables, and carefully formatted text and hyperlinks, making for a very powerful medium through which to present information. However, aside from the very low-level interactivity of hyperlinks and their ability to move the user from one page to another in a stream of information flowing from one page to another, HTML by itself allows for no true interactivity. HTML does not allow the web page to react to user input in any way beyond navigating to another page. HTML is an excellent way to allow for the presentation of information but does not allow for the interactivity required to transform web pages from an information medium to a dynamic web application solution.
Netscape Communications, along with Sun Microsystems, created a solution called LiveScript that allowed for the inclusion of limited programming instructions that reside in web pages viewed using the Netscape Navigator browser on the client machine. This programming language was limited in its ability to interact with the user's machine outside the browser and slowly over an evolving process was made safe and secure. You could not use LiveScript programming instructions on the client machine to undermine the security innate to the Netscape Navigator browser. LiveScript, in accordance with the marketing frenzy surrounding Java, was quickly renamed to JavaScript. Unfortunately, this renaming has led, erroneously, to its being thought of by many as a subset of the powerful Java language, although only its syntax is similar to that of Java.
HTML was enlivened. Using JavaScript, you could build forms and mortgage calculators and all sorts of interactive web pages. The only drawback was that your browser had to be a scripting host for this scripting language. But that being said, web content quickly went from being static and largely simple to being interactive and alive.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Server-Side Scripting
The last section served to introduce you to client-side scripting: how to include scripting code in the web pages that are viewed by your users. Now you will learn how to bring the power of scripting to the server and harness it to dynamically create HTML in reaction to user requests.
As you will recall from the last chapter, when the browser makes a request for a file ending with the .ASP file extension, IIS knows to bring ASP.DLL into play to interpret the ASP code in the file. Once interpreted, the results of this code are placed into the document, which is a simple HTML document before it is sent to the user.
How does ASP.DLL know which code to interpret? The answer to this question is the key to executing code on the server. ASP.DLL interprets all code in a file (with the .ASP file extension) that's delimited with <% ...%> as being ASP code. (There is another way to delineate server-side code that I'll cover in a moment.) Example 2.2 shows an active server page named ExampleChap2.ASP, with the VBScript code that will be interpreted by ASP.DLL in bold.
Example 2.2. ExampleChap2.ASP
<HTML>
<HEAD><TITLE>Example</TITLE></HEAD>
<BODY>
<%
' Construct a greeting string with a salutation and the
' current time on the server (retrieved from the Time( )
' function) and then display that in the HTML sent to the
' client.
strGreetingMsg = "Hello. It is now " & Time( ) & _
                 " on the server."
Response.Write strGreetingMsg
%>
</BODY>
</HTML>
When a user requests ExampleChap2.ASP, IIS pulls the file from the file system into its memory. Recognizing the .ASP extension from the settings in the Management Console, it uses ASP.DLL to read and interpret the file. Once interpreted, IIS sends the final result down to the requesting client browser.
IIS handles all the HTTP traffic. ASP.DLL only interprets server-side code, pulling in the DLL of the appropriate scripting engine when necessary. Let's assume the time is 10:42:43. The previous ASP file, once interpreted, would result in the following dynamically created HTML page that will in turn be sent to the client by IIS:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
ASP Functions
Code reuse is as important in Active Server Pages as it is in any other form of application programming. The first example of code reuse is the ASP function or subroutine. As I mentioned in the beginning of this chapter, there is one other way to delineate server-side code: the RUNAT attribute of the <SCRIPT> tag. You can use the RUNAT attribute to specify that a particular function or subroutine is to be run (and called from) the server side. Example 2.5 demonstrates the use of the RUNAT attribute to create a simple function that uses the last three letters of the domain string to return the general type of site that it represents. This function takes a domain string such as perl.ora.com and returns the string "company." The RUNAT attribute instructs ASP that this is a server-side-only function. It will not be sent to the client and is a valid function to call from within the server-side code. We could now incorporate that into a script, as shown in Example 2.6.
Example 2.5. Using the RUNAT Attribute to Create a Server-Side Function
<SCRIPT LANGUAGE = "VBScript" RUNAT = SERVER>
Function DomainType(strDomainString)

   strPossibleDomain = Right(strDomainString, 3)

   Select Case Ucase(strPossibleDomain)
      Case "COM"
         DomainType = "company"
      Case "EDU"
         DomainType = "educational"
      Case "GOV"
         DomainType = "government_civil"
      Case "MIL"
         DomainType = "government_military"
      Case Else
         DomainType = "UNKNOWN"
   End Select

End Function
</SCRIPT>
Example 2.6. Including a Server-Side Function in an ASP
<HTML><HEAD><TITLE>Function Example</TITLE></HEAD>
<BODY>
<%
' In this script we'll simply initialize a string
' example parameter, but this value could have
' come from another script.
strDomainString = "perl.ora.com"
strDomainType = DomainType(strDomainString)
%>
<%=strDomainString%> is a <%=strDomainType%> site.
</BODY>
</HTML>

<SCRIPT LANGUAGE = "VBScript" RUNAT = SERVER>
Function DomainType(strDomainString)

   strPossibleDomain = Right(strDomainString, 3)

   Select Case Ucase(strPossibleDomain)
      Case "COM"
         DomainType = "company"
      Case "EDU"
         DomainType = "educational"
      Case "GOV"
         DomainType = "government_civil"
      Case "MIL"
         DomainType = "government_military"
      Case Else
         DomainType = "UNKNOWN"
   End Select

End Function
</SCRIPT>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Scripting Languages
You do not have to use one single language for the entire ASP application. There is no problem with mixing and matching for convenience. I typically use VBScript in server-side code and JavaScript on the client, but you are not forced to use a single language in either setting. You can, however, force ASP to default to a specific script by using the @LANGUAGE preprocessor ASP directive. ASP directives are covered in Chapter 11. For now, know that you can use the following line of code as the first in your script to force ASP to use JScript as the default scripting language when interpreting your code:
<%@ LANGUAGE = JScript%>
If you place this line anywhere but as the first line, you will receive an error. Also note that VBScript is the default for all server-side scripts. However, you can change this in the Application options for your ASP application's virtual directory. See Appendix D.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Extending Active Server Pages
Chapter 1, presented a very brief overview of the Active Server Pages application paradigm. This chapter covers the various extensions for ASP. Some of these are included with IIS 4.0 and ASP 2.0, and some are available via the World Wide Web.
Extending Active Server Pages applications usually takes the form of instantiating server-side objects that expose methods and properties that you can access through your server-side code. Microsoft includes many of these Active server components with IIS 5.0. For example, one of the server components included with IIS is the Browser Capabilities component. Once instantiated, a Browser Capabilities object allows you to discern details about the user's web browser: what scripting it supports, what platform it is running on, and so on. This component allows you to dynamically alter your site in response to the presence or absence of certain browsers.
As will be discussed in Chapter 9, you use the CreateObject method of the Server object to instantiate a server component. For example, to create a MyInfo object in your Active Server Page, you could use code similar to the following:
<%
' Declare local variables.
Dim objMyInfo

' Instantiate a MyInfo object.
Set objMyInfo = Server.CreateObject("MSWC.MyInfo")

' You can now initialize the values.
objMyInfo.PersonalName = "A. Keyton Weissinger"
...[additional code]
%>
As you see in this example, instantiating these server components is simple. Once instantiated, you can use any of an object's exposed methods or properties to extend your web application.
Although IIS comes with several server components, you also can write your own in any development language that can create COM objects, such as Microsoft Visual Basic, Visual C++, Visual J++, or Inprise's Delphi. The details of writing server components are beyond the scope of this book, so I would encourage you to read Developing ASP Components, by Shelley Powers, published by O'Reilly & Associates.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Application Object
In the context of Active Server Pages, an application is the sum of all the files that can be accessed through a given virtual directory and its subdirectories. This ASP application context is the same for all clients using the application. For example, a client from Thailand who requests pages from your /SearchApp virtual directory is accessing the same "application" as a second client from Sweden who is requesting pages from the same virtual directory—regardless of which specific web page within the virtual directory each is requesting.
Just as traditional standalone applications allow you to share information throughout the application, so too do ASP applications. You can share information among all clients of a given ASP application using the Application object. This built-in object represents the ASP application itself and is the same regardless of the number or type of clients accessing the application and regardless of what part or parts of the application those clients are requesting.
The Application object is initialized by IIS the moment the first client requests any file from within the given virtual directory. It remains in the server's memory until either the web service is stopped or the application is explicitly unloaded from the web server using the Microsoft Management Console.
IIS allows you to instantiate variables and objects with application-level scope. This means that a given variable contains the same value for all clients of your application. You also can instantiate server-side objects with application-level scope that likewise contain the same values for all clients. These application-level variables and objects can be accessed and changed from the context of any user's session and from any file within the current application.
As stated earlier, the Application object's initialization occurs when the first user of your application requests any file from within the virtual directory that the ASP application encompasses. This initialization can be thought of as setting aside memory for the given ASP application. The web server instantiates and initializes the Application object for you. However, you can customize this initialization by including code in a special optional file called
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Comments/Troubleshooting
Application-level variables are, in effect, global variables for your ASP application. The use of globals in ASP applications should be viewed with as much skepticism as the use of globals in traditional standalone applications, if not with more. The most important step is to painstakingly consider its scope before implementing any object or variable with application-level scope. There are very few instances in which using these ASP global variables is necessary.
With that warning, there are a few instances in which using application-level variables or objects is useful in creating functional ASP applications. One of the most important of these is maintaining application-specific statistics for your web site. Using application-level variables that are incremented at the beginning of each user session, for example, you could maintain a count of clients that have used your application. Although such web management tools as Microsoft Site Server perform similar tasks, their statistics are file-specific, not application-specific.
Some ASP literature has suggested using application-level objects for maintaining open ActiveX Data Objects (ADO) database connections for all application users. (For more information on ADO, see Chapter 12.) This is not a good use of application-level variables, since this approach prevents ODBC from pooling connections per individual pages. However, you could use an application-level variable to maintain an application-specific connection string for that same database connection.
There is one trap that you should be aware of when considering the use of application-level variables and objects. Consider the following scenario. You have two physical directories: c:\inetpub\wwwroot\MainApp and c:\inetpub\wwwroot\MainApp\SearchApp. These directories are mapped to the virtual directories /MainApp and /SearchApp, respectively. You have, in effect, an application within an application. The first client requests a page within the c:\inetpub\wwwroot\MainApp\SearchApp
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Collections Reference
Contents Collection
Application.Contents( Key )
The Contents collection of the Application object contains all the application-level scoped variables and objects added to the current application through the use of scripts (not through the use of the <OBJECT> tag).
Before examining how elements are added to the Contents collection, you must first understand the properties of the Contents collection. The Contents collection has three properties:
Item
Retrieves the value of a specific member of the Contents collection. You specify which member using a string key (whose value is obtainable using the index through the Key property, explained later in this section) or using an index number. For example, if you wish to initialize an element in the Contents collection with the value of Pi, you might use a line of code similar to the following:
Application.Contents.Item("Pi") = 3.14
In the preceding line of code, the desired element in the collection is specified using the key value "Pi." Thus initialized, you can then retrieve the value of this element of the Contents collection using the following line of code:
dblMyVar = Application.Contents.Item("Pi")
For reasons that will become clear in a moment, let's assume that this is the first element added to the Contents collection.
You could also retrieve the value of an element in the Contents collection using its index in the collection rather than a key, as demonstrated in the following line of code:
dblMyVar = Application.Contents.Item(1)
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Contents Collection Methods
Remove
Application.Contents.Remove( Key|Index)
Removes a specific member from the Contents collection. An addition in IIS 5.0, the Remove method allows you to remove from memory a specific variable from the Application's Contents collection without removing all the others.
Parameters
Key
A string variable that specifies the name of the specific member of the Contents collection to be removed.
Index
An integer variable that specifies the index of the member of the Contents collection to be removed.
Example
The following script removes two members of the Contents collection:
<%
' This script assumes you have set up two greeting salutations for all
' the members of your site based on time of day. You want to now 
' remove these from your site.
strAppMorningGreeting = Application("strAMGreet")
strAppEveningGreeting = Application("strPMGreet")

.
.
.
Application.Contents.Remove("strAMGreet")
Application.Contents.Remove("strPMGreet")
.
.
.
%>
Notes
The Remove method is an important addition to the Contents collection because it allows for better memory control and cleanup. It allows you to remove from memory some of your collection's elements without abandoning the user's session. As discussed earlier under the Item property of the Contents collection, it is very important to use a string key instead of an index when calling the Remove method. An element's index may change over the life of the application, and then your call to Remove using a stored index value may lead to unpredictable results.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Methods Reference
Lock
Application.Lock
The Lock method locks the Application object, preventing any other client from altering any variables' values in the Contents collection (not just those variables you alter before calling the Unlock method). The corresponding Unlock method is used to release the Application object so other clients can again alter the Contents collection variable values. If you fail to use the Unlock method, IIS will unlock the variable automatically at the end of the current Active Server Pages script or upon script timeout, whichever occurs first.
Parameters
None
Example
<%
' This script exists on the second page of a 
' multipage ASP application, so that users may
' or may not visit it. The example shows how you could
' see how many visitors the page has had.
' Assume that TotalNumPage2 starts at 0.

' Lock the Application object.
Application.Lock

intNumVisits = Application.Contents("TotalNumPage2")
intNumVisits = intNumVisits + 1
Application.Contents("TotalNumPage2") = intNumVisits

' Explicitly unlock the Application object.
Application.Unlock

' NOTE: Using the PageCnt.DLL would be a more
' efficient manner of doing this.

%>
<HTML>
<HEAD><TITLE>Home Page</TITLE></HEAD>
<BODY BGCOLOR = #ffffcc>
Welcome to our homepage. You are client number 
<%= Application.Contents("TotalNumPage2")%> to our site. Thank you for your patronage.
</BODY>
</HTML>
Notes
Any client connected to your web server can call a script that potentially could alter the value of a variable in the Application Contents collection. For this reason, it is a good idea to use the Lock and Unlock methods every time you reference or alter a variable in the Contents collection. This prevents the possibility of a client attempting to change a variable's value when another client is resolving that variable's value.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Events Reference
OnEnd
Application_OnEnd
The Application_ OnEnd event is triggered when the ASP application itself is unloaded from the web server (using the Microsoft Management Console) or when the application is inadvertently stopped for some reason (i.e., the web service is stopped on the web server). Application_OnEnd is called only once per application. The code for this event procedure resides in the GLOBAL.ASA file and is processed after all other code in the file. It is in the code for the Application_OnEnd event that you will "clean up" after any application-scoped variables.
Parameters
None
Example
' <<<<<<<<<<<<<<< FROM GLOBAL.ASA >>>>>>>>>>>>>>>>>>
' This code resides in the GLOBAL.ASA file at the
' root of the current application. The following
' procedure is processed only once for the current
' application.
' See Chapter 11 for more details on the GLOBAL.ASA file.

<SCRIPT LANGUAGE="VBScript" RUNAT=Server> 
Sub Application_OnEnd

' This code will run on the server when
' the application stops.
' This code saves the final count of an application
' use counter to a file.
Set filsysObj1 = _
    CreateObject("Scripting.FileSystemObject")
Set tsObj1 = filsysObj1.CreateTextFile("c:\usrcount.txt", _
             True)
tsObj1.WriteLine(Application.Contents("AppUserCount"))
tsObj1.Close

End Sub 
</SCRIPT> 

' <<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>
Notes
The use of the Application_OnEnd event is tricky. The Microsoft documentation suggests that the OnEnd event is triggered when there are no longer any active sessions. However, this is not the case. Only when the web service is interrupted or when the administrator explicitly unloads the application from the web server's memory (using the MMC) is OnEnd executed. You cannot assume that this event will ever be called from your application without something going wrong or direct intervention on your part. This is yet another reason to very carefully consider the implications before using application-level variables of any kind.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 5: ASPError Object
Introduced with ASP 3.0, the built-in ASPError object allows you to view detailed information about the last error that occurred in the script of an ASP page in the current session. This object, through its nine read-only properties, provides more detailed information about the type and source of errors than does the Err object provided in VBScript.
To use the ASPError object and its properties, you must call a new method of the Server object, GetLastError, which returns an ASPErrorObject with its properties' values set to reflect details about the last error that occurred in the script:
Dim objMyASPError
Set objMyASPError = Server.GetLastError
When you install IIS 5.0, by default, all preprocessing, script and runtime errors in ASP code cause IIS to stop processing the current script and redirect script execution to a custom error page named 500-100.ASP. This redirection occurs through an internal call to the Server.Transfer method which, as detailed in Chapter 9, shifts execution from one script to another while protecting all state information available in the first script.
The 500-100.ASP script (located by default in the C:\WINNT\Help\iisHelp\common directory) contains a call to the Server.GetLastError method. When this script is executed, it formats and displays the current property values of the ASPError object returned by this call to GetLastError.
You can use the default error page, 500-100.ASP, as-is; edit it to reflect your site's look and feel; or use the Internet Services Manager snap-in to redirect IIS to a page of your choosing (see Appendix D).
The properties, collections, methods, and events of the ASPError object are outlined in the following box.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Comments/Troubleshooting
Many beginning ASP developers use the following code to enable debugging of their scripts using the Err object in VBScript:
On Error Resume Next
If you include this line of code in your script, then only preprocessing and script (syntax) errors will cause IIS to call the Server.Transfer method and redirect script execution to your 500-100.ASP script (or custom error-handling script). Runtime errors will not cause IIS to transfer processing to 500-100.ASP. For example, if you use this line of debugging code, you will not necessarily catch the error in the following block of code:
Dim intCounter
For intCounter = 1 to 100
     intResult = intCounter / (intCounter - 100)
Next
In this snippet, you would have to add code before the Next statement to catch the division by zero error that will arise when intCounter is 100. Adding these lines to catch errors throughout your code is costly in processing time and error-prone in its own right, since you have to anticipate the line on which an error is likely to occur in order to effectively trap it. As a result, and because the ASPError object provides more information than the Err object, you should not use On Error Resume Next if you can avoid it.
Another excellent use of the ASPError object page, 500-100.ASP (or similar, customized scripts for errors) is to handle errors that occur in a publicly available site. For example, you could customize the 500-100.ASP script to contain your site's color scheme and background and to include a Help phone number that could connect the user experiencing difficulty with someone who could help. And support personnel can field the call more effectively if you take advantage of the more extensive range of information that the ASPError object can provide to the 500-100.ASP script.
Another possibility is to use 500-100.ASP to route an error notification to the appropriate personnel "in the background," and to hide the details of the error from the end user. This version of 500-100.ASP
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Properties Reference
ASPCode
objASPError.ASPCode
The ASPCode property holds a numeric code representing the ASP-specific error that occurred in the script that raised the error. This property is populated by IIS if the error occurred in processing the ASP script.
The ASPCode property is read-only.
Parameters
None
Example
This example assumes that the following code has been added to the default custom error script, 500-100.ASP, and that each of the three scripts shown at the end of the Comments/Troubleshooting section is used to raise an error that invokes it:
**** BEGIN ASPCode Example Script ****
<%
' This script demonstrates the use of the ASPCode
' property of the ASPError object.
Dim objMyASPError

Set objMyASPError = Server.GetLastError( )

Response.Write "The value of the ASPCode property is " & objMyASPError.ASPCode
%>
**** END ASPCode Example Script ****
When the error-generating scripts are executed, the preceding example script generates the following three responses:
Error Generating Script #1:
The value of the ASPCode property is [EMPTY]
Error Generating Script #2:
The value of the ASPCode property is ASP 0128
                  
Error Generating Script #3:
The value of the ASPCode property is [EMPTY]
Notes
As previously noted, the ASPCode property is not populated unless the error occurred when interpreting the ASP script itself. This covers all preprocessing directives.
ASPDescription
objASPError.ASPDescription
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
ASPError Example
The following script could be used as a custom version of 500-100.ASP. It demonstrates several of the items discussed in this chapter and others.
From the user's perspective, this script simply informs him or her that an error has occurred, that the developers of the application have been notified, and that the user should try his or her action again later. It also provides a number that the user can call for support. In the background, however, this script creates a mail message containing information about the offending error, the state of the application and about the specific user who was attempting the action in the application. This mail message is then routed to a developer mailbox.
Note that you could add more sophistication to the routing mechanism that could, for example, look up the appropriate recipient based on the script title. Also, you may want to log these error messages in a database for later review.
<%@ LANGUAGE="VBSCRIPT" %>
<%
Response.Buffer = TRUE
Response.Expires = 0

' Script Name:  500-100_Custom.ASP

' Description:  This script catches the last error and
' creates and sends a message via email
' to the responsible developer.

' Inputs: Will take whatever information was previously
' submitted into the error-raising script.

' Author: Keyton Weissinger


' Change Log:
' Date       Programmer      Notes
' ---------------------------------------------------
' 3/24/2000  AKW             Created script.


' *** Dimension local variables needed for script. ***

' Vars for user and server info.
Dim strUser
Dim strRemoteAddress
Dim strServerName
Dim strServerAddress

' Vars for ASPError object property values.
Dim strASPCode
Dim strASPDescription
Dim strCategory
Dim strColumn
Dim strDescription
Dim strFile
Dim strLine
Dim strNumber
Dim strSource

' Vars for Request collection values.
Dim intKey
Dim strQueryStringElement
Dim strQueryStringValue
Dim strCurrentQueryString
Dim strFormElement
Dim strFormValue
Dim strCurrentForm

' Var for all HTTP header data.
Dim strAllHTTP

' Vars for Mail Message and sending.
Dim strErrMsgBody
Dim strRecipient
Dim strSender
Dim objNewMail

' Flush the buffer to ensure that no response information is sent to the 
' client.
If Response.Buffer Then
   Response.Clear
   Response.Status = "500 Internal Server Error"
   Response.ContentType = "text/html"
   Response.Expires = 0
End If

' *** Initialize the user and server variables. ***
strUser = Request.ServerVariables("REMOTE_USER")
strRemoteAddress = Request.ServerVariables("REMOTE_HOST")
strServerName = Request.ServerVariables("SERVER_NAME")
strServerAddress = Request.ServerVariables("LOCAL_ADDR")

' *** Initialize the ASPError object. ***
Set objASPError = Server.GetLastError( )

' *** Initialize the ASPError object property value variables. ***
strASPCode         = objASPError.ASPCode
strASPDescription  = objASPError.ASPDescription
strCategory        = objASPError.Category
strColumn          = objASPError.Column
strDescription     = objASPError.Description
strFile            = objASPError.File
strLine            = objASPError.Line
strNumber          = objASPError.Number
strSource          = objASPError.Source

' *** Retrieve the keys and values from the QueryString. ***
For Each intKey in Request.QueryString
     strQueryStringElement = Request.QueryString.Key(intKey)
     strQueryStringValue = Request.QueryString.Item(strQueryStringElement)
     strCurrentQueryString = strCurrentQueryString & "Element: " & _
     strQueryStringElement & ".......Value: " & strQueryStringValue & _
           Chr(10) & Chr(13)
Next

' *** Retrieve the keys and values from the Form. ***
For Each intKey in Request.Form
     strFormElement = Request.Form.Key(intKey)
     strFormValue = Request.Form.Item(strFormElement)
     strCurrentForm = strCurrentForm & "Element: " & _
     strFormElement & ".......Value: " & strFormValue & _
           Chr(10) & Chr(13)
Next

' *** Retrieve the keys and values from all HTTP headers 
' sent by client. ***
strAllHTTP = Request.ServerVariables("ALL_HTTP")

' *** Construct the error email message body string. ***
strErrMsgBody = "Greetings. An error has occurred." & Chr(10) & Chr(13) & _
     Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & _
     "Here is information that should help you debug the script."
strErrMsgBody = strErrMsgBody & Chr(10) & Chr(13) & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "User: " & strUser & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "User Address: " & strRemoteAddress & _
     Chr(10) & Chr(13) 
strErrMsgBody = strErrMsgBody & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "The error occurred on the following" _
     & "server: " & vbCrLf
strErrMsgBody = strErrMsgBody & "Server Name: " & strServerName & _
     vbCrLf
strErrMsgBody = strErrMsgBody & "Server I.P. Address: " & strServerAddress & _
     Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "ASP Error Information:" & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "ASPCode: " & strASPCode & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "ASPDescription: " & strASPDescription & _
     Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Category: " & strCategory & _
     vbCrLf
strErrMsgBody = strErrMsgBody & "Column: " & strColumn & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Description: " & strDescription & _
     vbCrLf
strErrMsgBody = strErrMsgBody & "File: " & strFile & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Line: " & strLine & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Number: " & strNumber & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Source: " & strSource & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & Chr(10) & Chr(13) & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Request.QueryString Information:" & _
     vbCrLf
strErrMsgBody = strErrMsgBody & strCurrentQueryString & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "Request.Form Information:" & _
     vbCrLf
strErrMsgBody = strErrMsgBody & strCurrentForm & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & "All HTTP headers sent by the client:" & _
     Chr(10) & Chr(13)
strErrMsgBody = strErrMsgBody & strALLHTTP & Chr(10) & Chr(13)

' Initialize the NewMail object and set the mail recipient, sender and body.
' Note you may want to insert your own code here to look up the specific 
' developer to which you want the error message sent.
Set objNewMail = Server.CreateObject("CDONTS.NewMail")
strRecipient = "Dev1@myapp.com"
strSender = strServerName & " at " & strServerAddress
objNewMail.Body = strErrMsgBody
objNewMail.To = strRecipient
objNewMail.From = strSender

' Send the email.
objNewMail.Send

' The rest of this script generates a non-specific error message for viewing 
' by the client.
' Customize its look and feel to match that of your site.
%>

<HTML>
<HEAD>
<TITLE>
Error Notice
</TITLE>
</HEAD>
<BODY>
We apologize for the inconvenience but your last action triggered an error on 
the web server.<BR>
A message has been sent to our development group and the error should be 
resolved shortly.<BR>
Please contact support at 800-555-HELP for more information or try your action
 again later.<BR><BR>
Thank you.
</BODY>
</HTML>
               
            
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 6: ObjectContext Object
As of version 2.0, an important feature of Active Server Pages is the ability to create a transactional script: one whose constituent code segments all succeed completely or fail as a group. For example, using such a script, one section of code could remove a record from an inventory table, and a second section could add a record to a sales log table. However, only if both sections of code succeed does the script itself succeed. If the removal of the inventory record or the addition of the sales rec