CHAPTER 2
Active Server Pages:
Server-Side Scripting



Chapter 1, Active Server Pages: An Introduction, 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) works to interpret
your server-side code to create HTML and how IIS then inserts that dynamically
created HTML into the HTML stream.

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, errone-
ously, 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.

Before JavaScript, all interaction with the user and all reaction on the part of the
web server required the use of sophisticated web server applications and higherend
web server machines. With the advent of JavaScript, the user’s machine was
now added to the equation, making it possible to offload some of this computational
power onto the client, whereas before it had rested solely on the server.

Not to be outdone, Microsoft Corporation quickly created a scripting language of
its own: Visual Basic, Scripting Edition, or VBScript for short. VBScript is a subset
of the Visual Basic for Applications language and, like JavaScript, it allows for the
creation of interactive web pages. Unlike JavaScript, whose syntax was similar to
that of Java (and thus similar to that of C++), the syntax of VBScript was exactly
that of Visual Basic. If you knew Visual Basic (and many, many people do), you
already had a good grasp on VBScript. Furthermore, Microsoft also created its own
version of JavaScript called JScript that was similar but not identical to its
predecessor.

Today (only a few short years later), JavaScript has undergone a transformation
into a new language built using submissions from both Netscape and Microsoft.
This new language is called ECMAScript (from European Computer Manufacturers
Association). According to David Flanagan in JavaScript: The Definitive Guide, this
name was chosen specifically because it had no relation to either parent company
and it had none of the marketing glitz of Java artificially associated with it. Both
Netscape and Microsoft have continued to help ECMAScript (still called JavaScript
by everyone except members of the European Computer Manufacturers Association)
evolve. For more details on the different browsers’ implementations,
Flanagan provides excellent coverage in his book.

Although the preceding discussion suggests that only JavaScript and VBScript exist,
the web browser actually allows for a multitude of scripting language alternatives.
You could even build your own. Some of the other languages include PerlScript,
Python, and Awk, with PerlScript being the most popular after JavaScript and
VBScript.

One thing all scripting languages have in common, however, is how they are
included on a web page and how the browser recognizes them as script and not
as HTML. All script is surrounded by matching <SCRIPT></SCRIPT> tags, as the
three examples of client-side script in Example 2-1 illustrate. Each of the three
routines performs exactly the same action: each displays a message box (or alert
box, depending on your preference of nomenclature) on the screen containing the
words “Hello world.”

There are two features in Example 2-1 to notice. The first is how the actual code is
surrounded by HTML comment symbols:

<!--
code here
-->

This lets the page be shown in browsers that do not support the <SCRIPT> tag
without causing problems or displaying the script on the page.

The second feature is the LANGUAGE attribute in each piece of sample code. The
LANGUAGE attribute of the <SCRIPT> tag, as you’ve undoubtedly guessed, indicates
what scripting language the browser should use to execute the included
code. This can be any language that your browser supports. JavaScript is probably
the safest bet for client-side scripting, since VBScript is supported only with the
use of plugins in non-Microsoft browsers, and other scripting languages are not
commonly installed on user machines. For more information about JavaScript, see
David Flanagan’s excellent book, JavaScript: The Definitive Guide, 3rd Edition. For
more information about VBScript, see Learning VBScript, by Paul Lomax. Both are
published by O’Reilly & Associates. We’ll revisit the question of scripting
languages at the end of this chapter.

Example 2-1: Client-Side Scripting Using Three Scripting Languages
<SCRIPT LANGUAGE = "JavaScript">
<!—-
Function AlertJS()
{
alert("Hello world.")
}
-->
</SCRIPT>
<SCRIPT LANGUAGE = "VBScript">
<!—-
Sub AlertVBS()
MsgBox "Hello world."
End Sub
-->
</SCRIPT>
<SCRIPT language="PerlScript">
<!—-
sub AlertPS()
{
$window->alert("Hello world.");
}
-->
</SCRIPT>

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.

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:
<HTML>
<HEAD><TITLE>Example</TITLE></HEAD>
<BODY>
Hello. It is now 10:42:43 on the server.
</BODY>
</HTML>
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>

You will learn more about the Write method of the Response object in Chapter 7,
Response Object. For now, recognize it as one way of writing information from the
portion of the script that is interpreted on the server to the portion of HTML that
will be displayed on the browser.

It is important to recognize this for what it is. There is no magic here. We are
simply capturing the HTTP request. Then ASP.DLL interprets some code and alters
the HTTP response that is sent back to the client.

ASP.DLL is an ISAPI filter that alters the resulting HTTP response
stream in reaction to information in the HTTP request combined
with code in the requested document.

The Response.Write method call is one way of inserting code into the HTML
stream that is sent back to the client, but there is a shortcut for this method call:
the <%=…%> delimiters. Note the inclusion of the equal sign (=). The equal sign is
what differentiates this as a shortcut call to the Response.Write method and not
simply more ASP code to interpret.

The <%=…%> delimiters allow for some subtle effects that can allow you to
produce some powerful server-side/client-side HTML combinations. Here is
Example 2-2 rewritten using the <%=…%> delimiters:
<HTML>
<HEAD><TITLE>Example</TITLE></HEAD>
<BODY>
Hello. It is now <%=Time()%> on the server.
</BODY>
</HTML>
Using the <%=…%> delimiters is the same as using the Write method of the
Response object. It simply inserts into the HTML stream whatever is between the
opening <%= and the closing %>. If the content between the delimiters represents a
variable, that variable’s value is inserted into the HTML stream. If the content is a
call to a function, the result of the function call is inserted into the HTML stream.
With the careful use of these delimiters, you can dynamically construct not only
HTML content but also client-side script code, as Example 2-3 demonstrates. The
script is called DynamicForm.asp, and it accepts a single parameter, button_
Count. Based on the value of button_Count, DynamicForm.asp will dynamically
build between one and ten HTML submit buttons and also dynamically generate
script for the onClick events for each of them. We will discuss this script in detail.
Example 2-3: DynamicForm.asp
<HTML>
<HEAD><TITLE>DynamicForm.asp</TITLE></HEAD>
<BODY>
Welcome to the dynamic form!
<%
' Retrieve the number of buttons the user wishes to create.
Suppose we call this script with the following line:
/DynamicForm.asp?button_Count=3
The result appears in Figure 2-1, and the resulting HTML source is shown in
Example 2-4.
intCmdCount = Request.QueryString("button_Count")
' Ensure that the sent parameter is within the acceptable
' limits.
If intCmdCount < 1 Then
intCmdCount = 1
End If
If intCmdCount > 10 Then
intCmdCount = 10
End If
' Create the buttons.
For intCounter = 1 to intCmdCount
%>
<INPUT TYPE = button VALUE = Button<%=intCounter%>
OnClick = "Button<%=intCounter%>_Click()">
<%
Next
%>
<SCRIPT LANGUAGE = "VBScript">
<%
' Create the scripts for each of the created buttons.
For intCounter = 1 to intCmdCount
%>
Sub Button<%=intCounter%>_Click()
MsgBox "You just clicked button <%=intCounter%>."
End Sub
<%
Next
%>
</SCRIPT>
</BODY>
</HTML>

The parameter button_Count=3 translated into the construction of three HTML
button elements and the corresponding code to go with them. Note the names and
the onClick event procedure names for each of these buttons (in bold in the
following code):
<INPUT TYPE = button VALUE = Button1
OnClick = "Button1_Click()">

Figure 2-1: The web page that results from invoking DynamicForm.ASP

Example 2-4: HTML Source Produced by DynamicForm.ASP
<HTML>
<HEAD><TITLE>DynamicForm.asp</TITLE></HEAD>
<BODY>
Welcome to the dynamic form!
<INPUT TYPE = button VALUE = Button1
OnClick = "Button1_Click()">
<INPUT TYPE = button VALUE = Button2
OnClick = "Button2_Click()">
<INPUT TYPE = button VALUE = Button3
OnClick = "Button3_Click()">
<SCRIPT LANGUAGE = "VBScript">
Sub Button1_Click()
MsgBox "You just clicked button 1."
End Sub
Sub Button2_Click()
MsgBox "You just clicked button 2."
End Sub
Sub Button3_Click()
MsgBox "You just clicked button 3."
End Sub
</SCRIPT>
</BODY>
</HTML>

<INPUT TYPE = button VALUE = Button2
OnClick = "Button2_Click()">
<INPUT TYPE = button VALUE = Button3
OnClick = "Button3_Click()">
These button element names and event procedure titles each came from the
following line of code:
<INPUT TYPE = button VALUE = Button<%=intCounter%>
OnClick = "Button<%=intCounter%>_Click()">
Note that the result of <%=intCounter%> is inserted into the HTML text stream.
Using ASP, we were able to dynamically generate names for each of our buttons
by appending the value of a counter variable onto the end of the word “Button” in
the HTML stream.

This is a subtle point. One of the most common errors in ASP development is to
treat the result of <%=…%> as a variable name. For example, the following line of
server-side code does not result in the greeting “Hello Margaret,” though some
developers mistakenly believe it does:
<%
' INCORRECT CODE.
strUserName = "Margaret"
%>
MsgBox "Hello " & <%=strUserName%>
When the preceding is sent to the client, it will appear like this:
MsgBox "Hello " & Margaret
VBScript tries diligently to make something of the token Margaret, but the result
is shown in Figure 2-2.
The correct line of code to produce the desired result is the following:
MsgBox "Hello <%=strUserName%>"
The point here is that what’s in the <%=…%> delimiters comes into the HTML
stream as is, even inside a string. Whatever the value of the content is, that is what
is inserted into the HTML stream. Do not treat <%=…%> as a variable.

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
Figure 2-2: Treating the result of <%=...%> as a variable name
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 www.oreilly.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)
The script in Example 2-6, once interpreted, generates and sends the following
script to the client:
<HTML>
<HEAD><TITLE>Function Example</TITLE></HEAD>
<BODY>
perl.ora.com is a company site.
</BODY>
</HTML>
Note that neither the text between the <%…%> delimiters nor the DomainType
function is present in the resulting HTML.
The script in Example 2-6 also demonstrates that we need not place our serverside
functions within the <HTML>…</HTML> tags. However, if we do (as in
Example 2-7), the resulting HTML will be exactly the same as it was before. The
server-side function is still not inserted into the HTML stream, even when we place
it inside the <BODY> tags.
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-7: Script Placed Within the <HTML>…</HTML> Tags
<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.
<SCRIPT LANGUAGE = "VBScript" RUNAT = SERVER>
Function DomainType(strDomainString)
strPossibleDomain = Right(strDomainString, 3)


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 10, Preprocessing Directives, Server-Side Includes, and
GLOBAL.ASA. 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 C, Configuration of ASP Applications on IIS.
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>
</BODY>
</HTML>

Chapter 3