Active Server Pages

Active Server Pages (ASP) is a server-side scripting environment that you can use to create dynamic Web pages or build powerful Web applications. ASP pages are files that contain HTML tags, text, and script commands. ASP pages can call ActiveX components to perform tasks, such as connecting to a database or performing a business calculation. With ASP, you can add interactive content to your Web pages or build entire Web applications that use HTML pages as the interface to your customer.

The topics in this section introduce Active Server Pages, explain the basic concepts of scripting with Active Server Pages, and discuss more complex application issues such as how to maintain state.

This section contains:

  • Introducing Active Server Pages: Introduces ASP and describes new features in this release.
  • Using Scripting Languages: Provides the basic information you need to write a script, including information on the language syntax.
  • Writing Simple Scripts: Provides information on writing scripts to perform basic tasks, such as getting information from an HTML form.
  • ASP Applications: Provides the more complex information you need to write applications, such as managing session state.

This section does not contain information on:

  • Information on more advanced topics, such as using session state; see ASP Applications
  • Reference pages for the built-in ASP objects
  • Reference pages for the components that come with ASP
  • Building your own ASP components
  • Reference pages for VBScript
  • Reference pages for JScript
  • Sample scripts provided with the SDK


Introducing Active Server Pages

Active Server Pages (ASP) makes it easy to generate dynamic content for the Web and to build powerful Web applications. Whether you are a Web designer or a Web developer, this introduction explains how ASP can help you.

This section contains:

  • About Active Server Pages: Provides an overview of Active Server Pages.
  • What's New in ASP: Describes new features added in this release.

This section does not contain information on:

  • Fundamental concepts of writing ASP scripts; see Using Scripting Languages.
  • Information on writing scripts to perform basic tasks; see Writing Simple Scripts.
  • Information on writing more advanced scripts; see ASP Applications.
  • Reference pages for the ASP objects and components and for the scripting languages.


About Active Server Pages

Microsoft® Active Server Pages (ASP) is a server-side scripting environment that you can use to create and run dynamic, interactive Web server applications. With ASP, you can combine HTML pages, script commands, and ActiveX components to create interactive Web pages or powerful Web-based applications. ASP applications are easy to develop and modify.

For the HTML Author

If you are an HTML author, you will find that ASP scripts are an easy way to begin creating interactive pages. If you have ever wanted to collect information from an HTML form, personalize an HTML document with a customer's name, or use different HTML features based on the browser, you will find that ASP provides a compelling solution. Previously, to collect information from an HTML form, you would have had to learn a programming language to build a Common Gateway Interface (CGI) application. Now you can collect and analyze data from a form by using simple instructions that you embed directly into your HTML documents. You do not need to learn a full programming language or compile programs separately to create interactive pages.

As your skill with ASP and scripting languages grows, you can create increasingly complex scripts. With ASP, you can easily use ActiveX components to perform complex tasks, such as connecting to a database to store and retrieve information.

For the Experienced Script Author

If you already know a scripting language, such as VBScript, JavaScript, or PERL, you already know how to use Active Server Pages. In your ASP pages you can use any scripting language for which you have installed a scripting engine that follows the ActiveX Scripting standard. ASP comes with scripting engines for Microsoft® Visual Basic® Scripting Edition (VBScript) and Microsoft® JScript™ so that you can immediately begin writing scripts. ActiveX Scripting engines for PERL, REXX, and Python are available through third-party developers.

For the Web Developer

If you already know a programming language, such as Visual Basic, you will find ASP a flexible way to quickly create Web applications. By adding script commands to HTML pages, you create an HTML interface for your application. By creating your own ActiveX components, you can encapsulate your application's business logic into reusable modules that you can call from a script, from another component, or from another program.

Web computing with ASP translates into tangible benefits, enabling Web providers to provide interactive business applications rather than merely publishing content. For example, a travel agency can do more than just publish flight schedules; it can use ASP scripting to enable customers to check available flights, compare fares, and reserve a seat on a flight.

Microsoft Transaction Server (MTS), which is included in the Windows NT Option pack, reduces the complexity and cost of building applications on the server. MTS handles the complexities of developing secure, scalable, and reliable Web applications.

The Active Server Pages Model

An ASP script begins to run when a browser requests an .asp file from your Web server. Your Web server then calls ASP, which reads through the requested file from top to bottom, executes any script commands, and sends a Web page to the browser.

Because your scripts run on the server rather than on the client, your Web server does all the work involved in generating the Web pages that you send to browsers. You need not worry whether a browser can process your scripts: your Web server does all the script processing, transmitting standard HTML to the browser. Server-side scripts cannot be readily copied because only the result of the script is returned to the browser. Your users cannot view the script commands that created the page they are viewing.


What's New in ASP

Active Server Pages has been enhanced with features that make it easier to use while developing applications.

  • Microsoft Script Debugger. You can use the Script Debugger to interactively debug .asp files. See Debugging ASP Scripts.
  • Transactional scripts. ASP pages and the objects used on the page can be run under a transaction context. All work done on that page will either be committed or aborted. Transactions protect your applications from failures that might cause loss of data. See Creating Transactional Scripts.
  • Administration tool. Many application settings are now available in Internet Service Manager, the administrative tool for Internet Information Server and Personal Web Server (on Windows NT Workstation).
  • Isolated ASP applications. You can now isolate ASP applications so that they run in a separate memory space from the Web server. This protects your other applications, and the Web server, in case an application fails. It also makes it possible for you to stop an application and unload its components from memory without stopping the Web server.
  • File upload. Browsers can now upload files to the Web server by using the Posting Acceptor application. You can write ASP scripts to send email with information passed from the Posting Acceptor, such as the location and name of each uploaded file. See the documentation for Posting Accepter (under Microsoft Site Server Express in the table of contents).
  • New ASP components. ASP provides new base components; see ActiveX Components for an overview.
  • Application root changes. The root directory of an ASP application can now be a physical directory within your Web site. Previously, the root directory had to be a virtual directory. You can now use Internet Service Manager to indicate the root of an ASP application. You must put .asp files in an application tree for the Web server to detect changes to the files and automatically reload them.
  • Support for Internet Explorer 4.0 channels and Web casting. ASP automatically tells Internet Explorer 4.0 when it is sending a file containing channel definition commands. You can now use ASP to easily generate channel definition (.cdf) files.
  • Support for HTTP 1.1 protocol. Internet Information Server and Personal Web Server support the HTTP 1.1 protocol. This support enables ASP to take advantage of efficiencies in the new protocol when responding to a browser that supports HTTP 1.1 (such as Internet Explorer 4.0). For example, ASP uses chunked transfer encoding to improve network efficiency when returning pages to a browser.


Using Scripting Languages

Active Server Pages provides a framework for using existing scripting languages, such as Microsoft VBScript and Microsoft JScript, in an HTML page. This section explains how to create an ASP page, how to add scripting language statements, and how to perform basic tasks such as creating an instance of an object. While these topics introduce some scripting and programming concepts, they are not intended to teach you a scripting language. The Microsoft scripting languages provide their own documentation, and many additional scripting books are available from your local bookseller. Whether you are a beginning or experienced script author, you should review these topics to learn the basic structure and syntax of using script languages in ASP pages. If you are new to scripting, however, you should also take advantage of the many books and classes to master these languages.

This section contains:

  • Creating ASP Pages: Describes an ASP page and explains how to add script commands to a page.
  • Working with Scripting Languages: Explains how to set the primary language and how to use VBScript and JScript in server scripts.
  • Using Variables and Constants: Provides an introduction to using variables in ASP scripts and explains how to access constant definitions.
  • Writing Procedures: Explains how to define procedures (functions and subroutines) and call them from ASP scripts.
  • Using Components and Objects: Explains how to create an instance of an object provided by an ActiveX component, how to use the ASP built-in objects, and how to use the methods and properties of any object.
  • Using Collections: Explains how to access items in a built-in object's collections, including access by iterating through a collection.
  • Setting Object Scope: Explains the scope, or extent, of an object and describes how to create session or application scope objects.
  • ASP Built-in Objects: Provides a quick overview of the ASP built-in objects with links to more detailed information.
  • ActiveX Components: Provides a quick overview of the ActiveX components that ASP provides, with links to more detailed information.

This section does not contain information on:

  • Information on writing scripts to perform basic tasks; see Writing Simple Scripts.
  • Information on writing more advanced scripts; see ASP Applications.
  • Reference pages for the ASP objects and components and for the scripting languages: see Scripter's Reference.


Creating ASP Pages

An Active Server Pages (ASP) file is a text file with the extension .asp that contains any combination of the following:

  • Text
  • HTML tags
  • ASP script commands

It’s easy to create an .asp file. For any HTML file to which you want to add scripts, rename the file by replacing the existing .htm or .html file name extension with .asp. To make the .asp file available to Web users, save the new file in a directory on your Web site (be sure that the directory has Script or Execute permission enabled). When you view the file with your browser, you see that ASP processes and returns an HTML page. You can now add script commands to the .asp file.

Note Because .asp files require extra processing, you should not convert all of your HTML pages into ASP pages. Convert only the files that will have script commands into .asp files. You can put both .asp and .htm files in the same directory.

You can use any text editor to create .asp files. You may find it more productive to use an editor with enhanced support for ASP, such as Microsoft® Visual InterDev™. If you have never used HTML before, consider getting started with Microsoft FrontPage. FrontPage lets you create documents and format text just as you would with a word processor. You can then add simple ASP commands to the HTML page created by FrontPage by using the Insert Script command.

Adding Script Commands

A script is a series of commands or instructions. Unlike HTML tags, which simply format text or read in a graphic, video, or sound file, a script command instructs the Web server to perform an action. Script commands can store a user’s name in a variable, display the user’s name in a page returned to the browser, or store the user’s name in a database.

Script commands are differentiated from text by delimiters. A delimiter is a character or sequence of characters that marks the beginning or end of a unit. In the case of HTML, these delimiters are the less than (<) and greater than (>) symbols, which enclose HTML tags.

ASP uses the delimiters <% and %> to enclose script commands. You can include within the delimiters any command that is valid for the scripting language you are using. The following example shows a simple HTML page that contains a script command:

<HTML>
<BODY>
This page was last refreshed on <%= Now %>.
</BODY>
</HTML>

The VBScript function Now returns the current date and time. When the Web server processes this page, it replaces <%= Now %> with the current date and time and returns the page to the browser:

This page was last refreshed on 8/1/97 2:20:00 PM.

Commands enclosed by delimiters are called primary script commands. These commands are processed using the primary scripting language. Any command that you use within script delimiters must be valid for the primary scripting language. By default, the primary scripting language is VBScript. You can set a different language. See Working with Scripting Languages.

If you are already familiar with client-side scripting (writing scripts that run on the browser), note that you do not use the HTML <SCRIPT> element to enclose expressions. For server-side scripting, you only use the <SCRIPT> element to define procedures in languages other than the primary scripting language. For more information, see Working with Scripting Languages.

Mixing HTML and Script Commands

You can include within ASP delimiters any statement, expression, procedure, or operator that is valid for your primary scripting language. A statement, in VBScript and other scripting languages, is a syntactically complete unit that expresses one kind of action, declaration, or definition. The conditional If...Then...Else statement that appears below is a common VBScript statement.

<%
If Time >= #12:00:00 AM# And Time < #12:00:00 PM#  Then
  Greeting = "Good Morning!"
Else
  Greeting = "Hello!"
End If
%>

<%= Greeting %>

This statement stores either the value "Good Morning!" or the value "Hello!" in the variable greeting. The <%= Greeting %> command sends the current value of the variable to the browser.

Thus, a user viewing this script before 12:00 noon (in the Web server’s time zone) would see this line of text:

Good Morning!

A user viewing the script at or after 12:00 noon would see this line of text:

Hello!

You can include HTML text between the sections of a statement. For example, the following script, which mixes HTML within an If...Then...Else statement, produces the same result as the script in the previous example:

<% If Time >= #12:00:00 AM# And Time < #12:00:00 PM# Then %>
Good Morning!
<% Else %>
Hello!
<% End If %>

If the condition is true—that is, if the time is midnight or after, and before noon—then the Web server sends the HTML that follows the condition (“Good Morning”) to the browser; otherwise, it sends the HTML that follows Else (“Hello!”) to the browser. This way of mixing HTML and script commands is convenient for wrapping the If...Then...Else statement around several lines of HTML text. The previous example is more useful if you want to display a greeting in several places on your Web page. You can set the value of the variable once and then display it repeatedly.

Rather than interspersing HTML text with script commands, you can return HTML text to the browser from within a script command. To return text to the browser, use the ASP built-in object Response. The following example produces the same result as the previous scripts:

<%
If Time >= #12:00:00 AM# And Time < #12:00:00 PM#  Then
  Response.Write "Good Morning!"
Else
  Response.Write "Hello!"
End If
%>

Response.Write sends the text that follows it to the browser. Use Response.Write from within a statement when you want to dynamically construct the text returned to the browser. For example, you might want to build a string that contains the values of several variables. You will learn more about the Response object, and objects in general, in Using Components and Objects and Sending Content to the Browser. For now, simply note that you have several ways to insert script commands into an HTML page.

You can include procedures written in your default primary scripting language within ASP delimiters. Refer to Working with Scripting Languages for more information.

If you are working with JScript commands, you can insert the curly braces that indicate a block of statements directly into your ASP commands even if they are interspersed with HTML tags and text. For example:

<% if (screenresolution == "low") { %>
This is the text version of a page.
<% } else { %>
This is the multimedia version of a page.
<% } %>

Using ASP Directives

ASP provides directives that are not part of the scripting language you use. These directives are the output directive and the processing directives.

The ASP output directive <%= expression %> displays the value of an expression. This output directive is equivalent to using Response.Write to display information. For example, the output expression <%= sport %> sends the word climbing (the current value of the variable) to the browser.

The ASP processing directive <%@ keyword %> gives ASP information it needs to process an .asp file. For example, the following directive sets VBScript as the primary scripting language for the page:

<%@ LANGUAGE=VBScript %>

The processing directive must appear on the first line of an .asp file. Do not put the processing directive in a file included with the #include statement. You must use a space between the at sign (@) and the keyword. The processing directive has the following keywords:

  • The LANGUAGE keyword sets the scripting language for the page. See Working with Scripting Languages.
  • The CODEPAGE keyword sets the code page (the character encoding) for the page. See Working with International Sites.
  • The LCID keyword sets the locale identifier for the page. See Working with International Sites.
  • The TRANSACTION keyword specifies that the page will run under a transaction context. See Creating Transactional Scripts.
  • The ENABLESESSIONSTATE keyword specifies whether an ASP page uses session state. See Managing Sessions.

You can include more than one keyword in a single directive; keyword/value pairs must be separated by a space. Do not put spaces around the equal sign (=). The following example sets both the scripting language and the code page:

<%@ LANGUAGE=JScript CODEPAGE=932 %>

White Space in Scripts

If your primary scripting language is either VBScript or JScript, ASP removes white space from commands. For all other scripting languages, ASP preserves white space so that languages that depend on position or indentation, such as Python, are correctly interpreted. White space includes spaces, tabs, returns, and line feeds.

For VBScript and JScript, you can use white space after the opening delimiter and before the closing delimiter to make commands easier to read. The following commands are all valid:

<% Color = "Green" %>

<%Color="Green"%>

<%
Color = "Green"
%>

ASP strips out white space between the closing delimiter of a statement and the opening delimiter of the following statement. If you need to preserve the white space between two statements, such as when you are displaying the values of variables in a sentence, use an HTML nonbreaking space character (&nbsp;). For example:

<%
'Define two variables with string values.
Hello = "Hello"
World = "World"
%>

<P>My response is to say "<%= Hello %>&nbsp;<%= World %>." </P>


Working with Scripting Languages

Scripting languages are an intermediate stage between HTML and programming languages such as Java™, C++, and Visual Basic. HTML is generally used for formatting text and linking pages. Programming languages are generally used for giving a series of complex instructions to computers. While scripting languages can also be used to give instructions to computers, their syntax and rules are generally less rigid and intricate than those of compiled programming languages. Scripting languages focus on formatting text or calling and using compiled components written in a programming language.

Active Server Pages makes it possible for the Web developer to write complete procedures by using a variety of scripting languages. In fact, several scripting languages can be used within a single .asp file. In addition, because scripts are read and processed on the server side, the client browser that requests the .asp file does not need to support scripting.

You can use any scripting language for which the appropriate scripting engine is installed on your Web server. A scripting engine is a program that processes commands written in a particular language. Active Server Pages comes with two scripting engines: Microsoft Visual Basic Scripting Edition (VBScript) and Microsoft JScript. You can install and use engines for other scripting languages, such as REXX and Perl.

If you are already a Visual Basic programmer, you can immediately begin using VBScript, which is a subset of Visual Basic. If you are a Java, C, or C++ programmer, you may find that JScript syntax is familiar to you, even though JScript is not related to Java or C.

If you are familiar with another scripting language, such as REXX or Perl, you can obtain and install the appropriate scripting engine so that you can use the language you already know. Active Server Pages is an ActiveX scripting host; to use a language you must install a scripting engine that follows the ActiveX Scripting standard and resides as a COM (Component Object Model) object on the Web server.

Setting the Primary Scripting Language

The ASP primary scripting language is the language used to process commands inside the <% and %> delimiters. By default, the primary scripting language is VBScript. You can use any scripting language for which you have a script engine as the primary scripting language. You can set the primary scripting language on a page-by-page basis, or for all pages in an ASP application.

Setting the Language for a Page

To set the primary scripting language for a single page, add the <%@ LANGUAGE %> directive to the beginning of your .asp file. The syntax for this directive is:

<%@ LANGUAGE=ScriptingLanguage %>

where ScriptingLanguage is the primary scripting language that you want to set for that particular page. The setting for a page overrides the global setting for all pages in the application.

Follow the guidelines for using an ASP directive; for more information, see Creating ASP Pages.

Note To use a language that does not support the Object.Method syntax as the primary scripting language, you must first create the LanguageEngines registry key.

Setting the Language for an Application

To set the primary scripting language for all pages in an application, set the Default ASP Language property on the App Options tab in Internet Service Manager.

Using VBScript and JScript on the Server

When using VBScript on the server with ASP, two VBScript features are disabled. Because Active Server Pages scripts are executed on the server, the VBScript statements that present user-interface elements, InputBox and MsgBox, are not supported. In addition, do not use the VBScript functions CreateObject and GetObject in server-side scripts. Use Server.CreateObject instead so that ASP can track the object instance. Objects created by CreateObject or GetObject cannot access the ASP built-in objects and cannot participate in transactions. The exception to this rule is when you are using the Admin Objects, and when you are using Java monikers. For more information, see Creating an Instance of a Java Class.

Including Comments

Because the processing of all ASP scripts is done on the server side, there is no need to include HTML comment tags to hide the scripts from browsers that do not support scripting, as is often done with client-side scripts. All ASP commands are processed before content is sent to the browser. You can use HTML comments to add remarks to an HTML page; comments are returned to the browser and are visible if the user views the source HTML.

VBScript Comments

Apostrophe-style comments are supported in VBScript. Unlike HTML comments, these are removed when the script is processed and are not sent to the browser.

<%
'This line and the following two are comments.
'The PrintTable function prints all
'the elements in an array.
Call PrintTable(myarray())
%>

You cannot include a comment in an output expression. For example, the first line that follows will work, but the second line will not, because it begins with <%=.

<% i = i +1 'this increments i. This script will work. %>

<%= name 'this prints the variable name. This script will fail. %>

JScript Comments

The // comment characters are supported in JScript. These characters should be used on each comment line.

<% Call PrintDate %>
<SCRIPT LANGUAGE=JScript RUNAT=Server>
// This is a definition for the procedure PrintDate.
function PrintDate()
{
  var x
  x = new Date()
  // This line sends the current date to the browser,
  // translated to a string.
  Response.Write(x.toString())
}
</SCRIPT>

Case Sensitivity

VBScript is not case sensitive. For example, you can use either Request or request to refer to the ASP Request object. One consequence of case-insensitivity is that you cannot distinguish variable names by case. For example, you cannot create two separate variables named Color and color.

JScript is case sensitive. When you use JScript keywords in scripts, you must type the keyword exactly as shown in the reference page for that keyword. For example, using date instead of Date will cause an error. In JScript, the names of objects must be capitalized; method and property names can be any case. The case shown in this documentation for the ASP built-in objects will work in JScript commands.


Using Variables and Constants

A variable is a named storage location in the computer's memory that contains data, such as a number or a text string. The data contained in a variable is called the variable's value. Variables give you a way to store, retrieve, and manipulate values using names that help you understand what the script does.

Declaring and Naming Variables

Follow the rules and guidelines of your scripting language for naming and declaring variables. Even if you are not required to declare a variable before using it, it is a good habit to develop because it helps prevent errors. Declaring a variable means to tell the script engine that a variable with a particular name exists so that you can use references to the variable throughout a script.

VBScript

VBScript does not require variable declarations, but it is good scripting practice to declare all variables before using them. To declare a variable in VBScript, use the Dim, Public, or Private statement. For example:

<% Dim UserName %>

You can use the VBScript Option Explicit statement in an .asp file to require variables to be explicitly declared. The Option Explicit statement must appear after any ASP directives and before any HTML text or script commands. This statement only affects ASP commands that are written in VBScript; it has no affect on JScript commands.

JScript

Microsoft JScript requires variable declarations only for variables that are local to a procedure, but it is good scripting practice to declare all variables before using them. To declare a variable, use the var statement. For example:

<% var UserName; %>

Variable Scope

The scope, or lifetime, of a variable determines which script commands can access a variable. A variable declared inside a procedure has local scope; the variable is created and destroyed every time the procedure is executed. It cannot be accessed by anything outside the procedure. A variable declared outside a procedure has global scope; its value is accessible and modifiable by any script command on an ASP page.

If you declare variables, a local variable and a global variable can have the same name. Modifying the value of one will not modify the value of the other. If you do not declare variables, however, you might inadvertently modify the value of a global variable. For example, the following script commands return the value 1 even though there are two variables named Y:

<%
Dim Y
Y = 1
Call SetLocalVariable
Response.Write Y

Sub SetLocalVariable
  Dim Y
  Y = 2
End Sub
%>

The following script commands, on the other hand, return the value 2 because the variables are not explicitly declared. When the procedure call sets Y to 2, the scripting engine assumes the procedure intended to modify the global variable:

<%
Y = 1
Call SetLocalVariable
Response.Write Y

Sub SetLocalVariable
  Y = 2
End Sub
%>

To avoid problems, develop the habit of explicitly declaring all variables. This is particularly important if you use the #include statement to include files into your ASP page. The included script is contained in a separate file but is treated as though it were part of the including file. It is easy to forget that you must use different names for variables used in the main script and in the included script unless you declare the variables.

Giving Variables Session or Application Scope

Global variables are accessible only on a single ASP page. To make a variable accessible beyond a single page, give the variable either session or application scope. Session-scoped variables are available to all pages in one ASP application that are requested by one user. Application-scoped variables are available to all pages in one ASP application that are requested by any user. Session variables are a good way to store information for a single user, such as preferences or the user's name or identification. Application variables are a good way to store information for all users of a particular application, such as an application-specific greeting or initial values needed by the application.

ASP provides two built-in objects into which you can store variables: the Session object and the Application object.

You can also create object instances with session or application scope. For more information, see Setting Object Scope.

Session Scope

To give a variable session scope, store it in the Session object by assigning a value to a named entry in the object. For example, the following commands store two new variables in the Session object:

<%
Session("FirstName") = "Jeff"
Session("LastName") = "Smith"
%>

To retrieve information from the Session object, access the named entry by using the output directive (<%=) or Response.Write. The following example uses the output directive to display the current value of Session("FirstName"):

Welcome <%= Session("FirstName") %>

You can store user preferences in the Session object, and then access those preferences to determine what page to return to the user. For example, you can allow a user to specify a text-only version of your content in the first page of the application and apply this choice on all subsequent pages that the user visits in this application.

<% If Session("ScreenResolution") = "Low" Then %>
This is the text version of the page.
<% Else %>
This is the multimedia version of the page.
<% End If %>

Application Scope

To give a variable application scope, store it in the Application object by assigning a value to a named entry in the object. For example, the following command stores an application-specific greeting in the Application object:

<% Application("Greeting") = "Welcome to Exploration Air" %>

To retrieve information from the Application object, use the ASP output directive output directive (<%=) or Response.Write to access the named entry from any subsequent page in the application. The following example uses the output directive to display the value of Application("Greeting"):

<%= Application("Greeting") %>

Using Constants

A constant is a name that takes the place of a number or string. Some of the base components provided with ASP, such as ActiveX Data Objects (ADO), define constants that you can use in your scripts. A component can declare constants in a component type library, a file that contains information about objects and types supported by an ActiveX component. Once you have declared a type library in your Global.asa file, you can use the defined constants in any script in the application.

To declare a type library, use the <METADATA> tag in the Global.asa file for your application. For example, to declare the ADO type library, use the following statements:

<!--METADATA TYPE="typelib"
FILE="c:\program files\common files\system\ado\msado15.dll"
-->

You can then use ADO constants in any script in the same application as the Global.asa file. In the following example, adOpenKeyset and adLockOptimistic are ADO constants:

'Create and Open Recordset Object
Set RsCustomerList = Server.CreateObject("ADODB.Recordset")
RsCustomerList.ActiveConnection = OBJdbConnection
RsCustomerList.CursorType = adOpenKeyset
RsCustomerList.LockType = adLockOptimistic

In previous versions of ASP, some components provided constant definitions in files that had to be included in each ASP file that used those constants. The use of the #include directive to include constant definitions is still supported, but type libraries are generally easier to use and make your scripts more easily upgraded. Components might not provide constant definition files in future releases of ASP.

You can define your own constants. In VBScript, use the Const statement. In JScript, use the var statement. If you want to use your constants on more than one ASP page, put the definitions in a separate file and include them in each ASP page that uses the constants.


Writing Procedures

A procedure is a group of script commands that performs a specific task and can return a value. You can define your own procedures and call them repeatedly in your scripts.

You can place procedure definitions in the same .asp file that calls the procedures, or you can put commonly used procedures in a shared .asp file and use the SSI #include directive to include it in other .asp files that call the procedures. Alternatively, you could package the functionality in an ActiveX component.

Defining Procedures

Procedure definitions can appear within <SCRIPT> and </SCRIPT> tags and must follow the rules for the declared scripting language. Use the <SCRIPT> element for procedures in languages other than the primary scripting language. Use the scripting delimiters (<% and %>) for procedures in the primary scripting language.

When you use the HTML <SCRIPT> tag, you must use two attributes to ensure server-side processing of the script. The syntax for using the <SCRIPT> tag is:

<SCRIPT RUNAT=SERVER LANGUAGE=JSCRIPT>
  procedure definition
</SCRIPT>

The RUNAT=SERVER attribute tells the Web server to process the script on the server. If you do not set this attribute, the script is processed by the client browser. The LANGUAGE attribute determines the scripting language used for this script block. You can specify any language for which you have the scripting engine. To specify VBScript, use the value VBSCRIPT. To specify JScript, use the value JSCRIPT. If you do not set the LANGUAGE attribute, the script block is interpreted in the primary scripting language.

The commands in the script block must form one or more complete procedures in the chosen scripting language. For example, the following commands define the JScript procedure MyFunction.

<HTML>
<SCRIPT RUNAT=SERVER LANGUAGE=JSCRIPT>
  function MyFunction()
  {
      Response.Write("MyFunction Called")
  }
</SCRIPT>

Important Do not include within server-side <SCRIPT> tags any script commands that are not part of complete procedures. Commands that are not part of a procedure may cause unpredictable results because the order of execution is not predictable. In addition, you cannot use the ASP output expression <%= within a procedure. Instead, you must use Response.Write.

Calling Procedures

To call procedures, include the name of the procedure in a command. If you are calling JScript procedures from VBScript, you must use parentheses after the procedure name; if the procedure has no arguments, use empty parentheses. If you are calling either VBScript or JScript procedures from JScript, always use parentheses after the procedure name.

For VBScript, you can also use the Call keyword when calling a procedure. However, if the procedure that you are calling requires arguments, the argument list must be enclosed in parentheses. If you omit the Call keyword, you also must omit the parentheses around the argument list. If you use Call syntax to call any built-in or user-defined function, the function’s return value is discarded.

The following example illustrates creating and calling procedures by using two different scripting languages (VBScript and JScript).

<%@ LANGUAGE = VBSCRIPT >%
<HTML>
<BODY>
<% Call Echo %>
<BR>
<% Call PrintDate() %>
</BODY>
</HTML>

<%
Sub Echo
  Response.Write "<TABLE>"
  Response.Write "<TR><TH>Name</TH><TH>Value</TH></TR>"
  Set Params = Request.QueryString
  For Each p in Params
    Response.Write "<TR><TD>" & p & "</TD><TD>" & _
    Params(p) & "</TD></TR>"
  Next
Response.Write "</TABLE>"
End Sub
%>

<SCRIPT LANGUAGE=JScript RUNAT=Server>
function PrintDate()
{
  var x
  x = new Date()
  Response.Write(x.toString())
}
</SCRIPT>

Passing Arrays to Procedures

To pass an entire array to a procedure in VBScript, use the array name followed by empty parentheses; in JScript, use empty square brackets.


Using Components and Objects

ActiveX components are the key to building powerful Web applications. Components provide objects that you use in your scripts to perform tasks. ASP also provides built-in objects that you can use in your scripts. This topic explains how to use the objects provided by any component as well as the built-in objects provided directly by Active Server Pages. For information on using an object's collections, see Using Collections.

About Components

An ActiveX component is a file containing code that performs a task or set of tasks. Components perform common tasks so that you do not have to create your own code to perform these tasks. For example, a stock ticker component might display the latest stock quotes on a Web page. ASP comes with base components that you can use immediately, such as the Database Access Component. You can obtain additional components from third-party developers. Or, you can write your own components.

You use components as the basic building blocks of your script or Web-based application. If you are new to scripting, you can write scripts that use components without knowing anything about how the component works. You simply need to know how to access the objects provided by the components. Components enable you to write powerful scripts without learning any programming.

If you are a Web application developer, you can write components to encapsulate business logic. For example, you could write a component to calculate the sales tax on a product sale. You could then call the component from a script that processes a sales order. Isolating the tax calculation from the order process enables you to update the component when the sales tax for an area changes without changing your order process. You can write components in any programming language that supports the Component Object Model (COM), such as C, C++, Java, or Visual Basic. If you are familiar with COM programming, ActiveX components are Automation servers. To run on the Web server, your ActiveX components cannot have any graphical user interface elements, such as the Visual Basic MsgBox function.

Components are reusable. Once you have installed a component on your Web server, you can call it from an ASP script, an ISAPI application, another component on the server, or a program written in another COM-compatible language.

Creating an Instance of a Component’s Object

A component is executable code contained in a dynamic-link library (.dll) or in an executable (.exe) file. A component provides one or more objects, along with the object’s methods and properties. To use an object provided by a component, you create an instance of the object and assign the new instance to a variable name. Use the ASP Server.CreateObject method to create the object instance. Use your scripting language’s variable assignment statement to give your object instance a name. When you create the object instance, you must provide its registered name (PROGID). For the base components provided with ASP, you can get the PROGID for the objects from the reference pages.

For example, the ASP Ad Rotator component randomly rotates through a series of graphical advertisements. The Ad Rotator component provides one object, called the Ad Rotator object, whose PROGID is "MSWC.AdRotator". To create an instance of the Ad Rotator object, use one of the following statements:

VBScript:

<% Set MyAds = Server.CreateObject("MSWC.AdRotator") %>

JScript:

<% var MyAds = Server.CreateObject("MSWC.AdRotator") %>

If you are already familiar with VBScript or JScript, notice that you do not use the scripting language’s function for creating a new object instance (CreateObject in VBScript or New in JScript). You must use the ASP Server.CreateObject method; otherwise, ASP cannot track your use of the object in your scripts.

You can also use the HTML <OBJECT> tag to create an object instance. You must supply the RUNAT attribute with a value of Server, and you must provide the ID attribute set to the variable name you will use in your scripts. You can identify the object by using either its registered name (PROGID) or its registered number (CLSID).The following example uses the registered name (PROGID) to create an instance of the Ad Rotator object:

<OBJECT RUNAT=Server ID=MyAd PROGID="MSWC.AdRotator"></OBJECT>

The following example uses the registered number (CLSID) to create an instance of the Ad Rotator object:

<OBJECT RUNAT=Server  ID=MyAd
CLASSID="Clsid:1621F7C0-60AC-11CF-9427-444553540000"></OBJECT>

Creating an Object from a Java Class

An ActiveX component written in Java can be delivered as a Java class instead of a DLL. To use Server.CreateObject to create an instance of an object exposed by the Java class, you must use the Javareg program to register the class as a COM component. You can then use Server.CreateObject with the PROGID or CLSID.

If the object instance does not need access to the ASP built-in objects and does not need to participate in a transaction, you can use the simpler mechanism provided by Java monikers to call the Java class directly. You must be using version 2.0 of the Microsoft virtual machine for Java (provided with this release of Internet Information Server and Personal Web Server) to use Java monikers.

To instantiate an object by using monikers, use the VBScript or JScript GetObject statement and provide the full name of the Java class in the form java:classname. The following VBScript example creates an instance of the Java Date object.

<%
Dim date
Set date = GetObject("java:java.util.Date")
%>

<p> The date is <%= date.toString() %>

Objects created by calling GetObject instead of Server.CreateObject cannot access the ASP built-in objects and cannot participate in a transaction.

Using ASP Built-in Objects

ASP provides built-in objects that perform tasks. For example, the Request object stores the data passed to the server from an HTML form. Unlike using the objects provided by an ActiveX component, you do not need to create an instance of an ASP built-in object to use it in your scripts. You access the methods and properties of a built-in object in the same way in which you access the methods and properties of a component’s objects, as described in this topic.

Calling an Object Method

A method is an action you can perform on an object or with an object. The general syntax for calling a method is:

Object.Method parameters

The parameters vary depending on the method.

For example, you can use the Write method of the Response built-in object to send information to the browser as shown in the following statement:

<% Response.Write "Hello World" %>

Note Some scripting languages do not support the Object.Methodsyntax. If your language does not, you must add an entry to the registry in order to use that language as your primary scripting language. See Working with Scripting Languages for more information.

Setting an Object Property

A property is an attribute that describes the object. Properties define object characteristics, such as the type of the object, or describe the state of an object, such as enabled or disabled. The general syntax is:

Object.Property

You can read the value of a property and set the value of a property. For some objects, you can also add new properties.

For example, the Ad Rotator component has a property, Border, that specifies whether the ad has a border around it and determines the border thickness. The following expression specifies no border:

<% MyAds.Border = 0 %>

For some properties, you can display the current value by using the ASP output directive. For example, the following command returns TRUE if the browser is still connected to the server:

<%= Response.IsClientConnected %>


Using Collections

Most of the ASP built-in objects support collections. A collection is a place to store strings, numbers, objects and other values. A collection is is similar to an array except that it expands and contracts automatically as items are stored in or retrieved from the collection. Unlike an array, the position of an item will move as the collection is modified. You can access an item in a collection by its name, by its index (position) in the collection, or by iterating through all the items in the collection.

Accessing an Item by Name or Index

You can access a specific item in a collection by using its name. For example, the Contents collection holds any variables stored in the Session object. It also holds any objects created by calling Server.CreateObject. Suppose you have stored the following user information in the Session object:

<%
Session.Contents("FirstName") = "Sam"
Session.Contents("LastName") = "Woo"
Session.Contents("Age") = 29
%>

You can access an item by using the name you associated with the item when you stored it in the collection. For example, the following expression returns the string "Sam":

<%= Session.Contents("FirstName") %>

You could also access an item by using the index, or number, associated with an item. For example, the following expression retrieves the information stored in the second slot of the Session object and returns "Woo":

<%= Session.Contents(2) %>

ASP collections are numbered starting with 1. The index associated with an item might change as items are added to or removed from the collection. You should not depend on an item’s index remaining the same. Indexed access is generally used to iterate through a collection, as described in the following topics, or to access an item in a read-only collection.

You can access items by name using a shorthand notation. ASP searches the collections associated with an object in a particular order. If an item with a particular name appears only once in an object's collections, you can eliminate the collection name:

<%= Session("FirstName") %>

Eliminating the collection name is generally safe when you are accessing items stored in the Application or Session object. For the Request object, however, it is safer to specify the collection name because the collections could easily contain items with duplicated names.

Iterating through a Collection

You can iterate through all the items in a collection to see what is stored in the collection or to modify the items. You must supply the collection name when you iterate through a collection. For example, you can use the VBScript For...Each statement to access the items you stored in the Session object:

<%
'Declare a counter variable.
Dim Item

'For each item in the collection, display its value.
For Each Item in Session.Contents
  Response.Write Session.Contents(Item) & "<BR>"
Next
%>

You can also iterate through a collection by using the VBScript For...Next statement. For example, to list the three items stored in Session by the previous example, use the following statements:

<%
'Declare a counter variable.
Dim Item

'Repeat the loop until the value of counter is equal to 3.
For Item = 1 to 3
  Response.Write Session.Contents(Item) & "<BR>"
Next
%>

Because you do not usually know how many items are stored in a collection, ASP supports the Count property for a collection, which returns the number of items in the collection. You use the Count property to specify the end value of the counter.

<%
'Declare a counter variable.
Dim Item

'Repeat this loop until the counter equals the number of items
'in the collection.
For Item = 1 to Session.Contents.Count
   Response.Write Session.Contents(Item) & "<BR>"
Next
%>

In JScript, you use the for statement to loop through a collection. For greater efficiency when using the Count property with a JScript for statement, you should assign the value of Count to a local variable and use that variable to set the end value of the counter. That way, the script engine does not have to look up the value of Count each time through the loop. The following example demonstrates this technique:

<%
var item, numitems;
numitems = Session.Contents.Count;
for (item = 1; item <= numitems; item++) {
  Response.Write(Session.Contents(item) + "<BR>")
}
%>

Version 3.0 of Microsoft JScript introduces a new Enumerator object that you can also use to iterate through an ASP collection. The atEnd method indicates whether there are any more items in the collection. The moveNext method moves to the next item in the collection.

<%
// Create an Enumerator object
var mycoll = new Enumerator(Session.Contents);

//Iterate through the collection and display each item
while (!mycoll.atEnd()) {
  var x  = mycoll.item();
  Response.Write(Session.Contents(x) + "<BR>");
  mycoll.moveNext();
}
%>

Iterating through a Collection with Subkeys

Scripts might embed several related values in a single cookie to reduce the number of cookies passed between the browser and the Web server. The Cookies collection of the Request and Response objects can thus hold multiple values in a single item. These subitems, or subkeys, can be accessed individually. Subkeys are supported only by the Request.Cookies and Response.Cookies collections. Request.Cookies supports only read operations; Response.Cookies supports only write operations.

You can enumerate all the cookies in the Request.Cookie collection and all the subkeys in a cookie. However, iterating through subkeys on a cookie that does not have subkeys will not produce any output. You can avoid this situation by first checking to see whether a cookie has subkeys by using the .HasKeys syntax. This technique is demonstrated in the following example.

<%
'Declare counter variables
Dim Cookie, Subkey

'Display the entire cookie collection.
For Each Cookie in Request.Cookies
  Response.Write Cookie & "<BR>"
    If Request.Cookies(Cookie).HasKeys Then
      'Display the subkeys
      For Each Subkey in Request.Cookies(Cookie)
    Response.Write Subkey & "=" & Request.Cookies(Cookie)(Subkey) & "<BR>"
      Next
    Else
      Response.Write "No subkeys in this cookie <BR>"
    End If
Next
%>

Iterating through a Collection of Objects

The Session and Application collections can hold either scalar variables or object instances. The Contents collection holds both scalar variables and object instances created by calling Server.CreateObject. The StaticObjects collection holds objects created by using the HTML <OBJECT> element in the Global.asa file.

When you iterate through a collection that contains objects, you can either access the object’s identifier or access the object’s methods or properties. For example, suppose your application uses several objects to create a user account, and each object has an initialization method. You could iterate through the StaticObjects collection to call each initialization method:

<%
For Each Object in Session.StaticObjects
  Session.StaticObjects(Object).InitializeUser
Next
%>

What’s Different About ASP Collections?

Although the ASP collections described in this topic are similar to the Visual Basic Collection object, there are some differences. The ASP collections support the Count property and the Item method. They do not support the Add and Remove methods.


Setting Object Scope

The scope of an object determines which scripts can use an object. By default, when you create an object instance, the object has page scope. Any script command in the same ASP page can use a page-scope object; the object is released when the ASP page is sent back to the client. The recommended scope for most objects is page scope. You can change the scope of an object, however, to make it accessible from scripts on other pages. This topic explains how to work with page scope objects and how to change the scope of objects.

Using Page Scope Objects

An object that you create by using Server.CreateObject on an ASP page exists for the duration of that page. The object is accessible to any script commands on that page, and it is released when ASP has finished processing the page. Thus an object has the scope, or lifetime, of a page.

If you have programmed in Visual Basic or VBScript, note that you cannot release an object before ASP has finished processing the page. For example, the following VBScript statement is often used to release an object by assigning the value Nothing to the object variable:

Set myObj = Nothing

If you include this statement in an ASP page, any attempt to use myObj will return an error code, as expected. Internally, however, ASP retains a reference to your object, even after you have released it. While you cannot use the object in your script, the object's resources are not released until ASP has finished processing the page. Similarly, if you release an object by creating a different object instance and assigning it to an object variable you have already used, ASP retains a reference to the original object instance. While creating many objects may not cause a problem for most scripts, it can cause problems if the objects use shared resources, such as database connections.

Because objects have page scope, do not depend on objects being released manually. For example, the following loop creates 1001 Connection objects, which would open most of the connections on even a large SQL server:

<%
For I = 0 to 1000
  Set Conn = Server.CreateObject("ADODB.Connection")
  Conn.Open "connection string"
Next
%>

In general, you should avoid creating objects inside a loop. If you must create objects in a loop, you should manually release the resources used by an object. The previous example works if the Connection object is created only once, and the physical connection to the data source is opened and closed during each loop:

<%
Set Conn = Server.CreateObject("ADODB.Connection")
For I = 0 to 1000
  Conn.Open "connection string"
  Conn.Close
Next
%>

Giving an Object Session Scope

A session-scope object is created for each new session in an application and released when the session ends; thus, there is one object per active session. Session scope is used for objects that are called from multiple scripts but affect one user session. You should give objects session scope only when needed. If you do use session scope, you must know the threading model of the component that provides the object because the threading model affects the performance and security context of the object. For more information, see “Advanced Information: Performance Issues” in this topic.

To give an object session scope, store the object in the ASP Session built-in object. You can use either the <OBJECT> tag in a Global.asa file or the Server.CreateObject method on an ASP page to create a session scope object instance.

In the Global.asa file, you can use the <OBJECT> tag, extended with RUNAT attribute (which must be set to Server) and the SCOPE attribute (which must be set to Session). The following example creates a session-scope instance of the Ad Rotator object:

<OBJECT RUNAT=Server SCOPE=Session ID=MyAd PROGID="MSWC.Adrotator">
</OBJECT>

Once you have stored the object in the Session object, you can access the object from any page in the application. The following statement uses the object instance created by the <OBJECT> tag in the previous example:

<%= MyAd.GetAdvertisement("addata.txt") %>

On an ASP page, you can also use the Server.CreateObject method to store an object in the Session built-in object. The following example stores an instance of the Ad Rotator object in the Session object.

<% Set Session("MyAd") = Server.CreateObject("MSWC.Adrotator") %>

To display an ad, you first retrieve the instance of the Ad Rotator object stored in the Session object, and then call the method to display an ad:

<% Set MyAd = Session("MyAd") %>
<%= MyAd.GetAdvertisement("addata.txt") %>

ASP does not instantiate an object that you declare with the <OBJECT> tag until that object is referenced by a script command from an .asp file. The Server.CreateObject method instantiates the object immediately. Thus, the <OBJECT> tag offers better performance than the Server.CreateObject method for session-scope objects.

Giving an Object Application Scope

An application-scope object is a single instance of an object that is created when the application starts. This object is shared by all client requests. Only rarely should you give an object application scope. Some utility objects, such as counters, might require application scope, but generally you should use the alternatives proposed in the following section. In addition, the threading model affects the performance and security context of the object (see “Advanced Information: Performance Issues” in this topic).

To give an object application scope, store the object in the ASP Application built-in object. You can use either the <OBJECT> tag in a Global.asa file or the Server.CreateObject method on an ASP page to create an application scope object instance.

In the Global.asa file, you can use the <OBJECT> tag, extended with RUNAT attribute (which must be set to Server) and the SCOPE attribute (which must be set to Application). On an ASP page, you can use Server.CreateObject to store an object instance in the Application built-in object. For examples of using the <OBJECT> tag and Server.CreateObject, see the previous section “Giving an Object Session Scope.”

Alternatives to Session and Application Scope

You should give objects session or application scope only when needed. Because these objects linger until the session or application has finished running, they consume resources, such as memory or database connections, that might be better used in other ways. In addition, the threading model of a component affects the performance of objects you create from it, especially objects with session or application scope.

In many cases, a better solution than creating application or session scope objects is to use session or application scope variables that pass information to objects created at the page level. For example, you should not give an ADO Connection object session or application scope because the connection it creates remains open for a long time and because your script no longer takes advantage of ODBC connection pooling. You can, however, store an ODBC connection string in the Session or Application built-in object and access the string from a Connection object instance that you create on a page. In this way, you store frequently used information in the session or application name space but you create the object that uses the information only when needed.

User-defined JScript Objects

You can create your own JScript object by defining a constructor function that creates and initializes the properties and methods of the new object. The object instance is created when your script uses the new operator to invoke the constructor. User-defined objects are supported in ASP scripts and work well when they have page scope. Giving a user-defined JScript object application or session scope, however, might affect the functionality of the object. In particular, if an object has session or application scope, scripts on other pages can access the object's properties but cannot call its methods.

Advanced Information: Performance Issues

The threading model of a component may affect the performance of your Web site. Generally, objects that are marked Both are the recommended objects to use in all ASP scripts, particularly in the Session and Application objects. Single-threaded objects are not recommended.

Because you may not always have control over the threading model of the objects you use, the following guidelines will help you get the best performance:

  • Page scope objects. Objects marked Both or Apartment will give you the best performance.
  • Application scope objects. In general, avoid putting objects in the Application object. If you do use application-scope objects, you will get the best performance from objects marked Both that aggregate the FreeThreadedMarshaler. You can use either the <OBJECT> tag or the Server.CreateObject method to store objects marked Single, Free, or Both in the Application object. You must use the <OBJECT> tag with apartment-threaded objects.
  • Session scope objects. Objects marked Both will give you the best performance. Using single-threaded or apartment-threaded objects will cause the Web server to lock the session down to one thread. Free-threaded objects do not lock down the session, but are slow. You can use either the <OBJECT> tag or the Server.CreateObject method to store objects in the Session object.


Built-in ASP Objects

Active Server Pages provides built-in objects that make it easier for you to gather information sent with a browser request, to respond to the browser, and to store information about a particular user, such as user-selected preferences. This topic briefly describes each object.

Application Object

You use the Application object to share information among all users of a given application.

Request Object

You use the Request object to gain access to any information that is passed with an HTTP request. This includes parameters passed from an HTML form using either the POST method or the GET method, cookies, and client certificates. The Request object also gives you access to binary data sent to the server, such as file uploads.

Response Object

You use the Response object to control the information you send to a user. This includes sending information directly to the browser, redirecting the browser to another URL, or setting cookie values.

Server Object

The Server object provides access to methods and properties on the server. The most frequently used method is the one that creates an instance of an ActiveX component (Server.CreateObject). Other methods apply URL or HTML encoding to strings, map virtual paths to physical paths, and set the timeout period for a script.

Session Object

You use the Session object to store information needed for a particular user session. Variables stored in the Session object are not discarded when the user jumps between pages in the application; instead, these variables persist for the entire time the user is accessing pages in your application. You can also use Session methods to explicitly end a session and set the timeout period for an idle session.

ObjectContext Object

You use the ObjectContext object to either commit or abort a transaction initiated by an ASP script.


Built-in ASP Objects Quick Reference Card

Application Object
Collections:
Contents
StaticObjects
Methods:
Lock
Unlock
Events:
Application_OnEnd
Application_OnStart

ObjectContext Object
Methods:
SetAbort
SetComplete
Events:
OnTransactionAbort
OnTransactionCommit

Request Object
Collections:
ClientCertificate
Cookies
Form
QueryString
ServerVariables
Properties:
TotalBytes
Methods:
BinaryRead
Response Object
Collections:
Cookies
Properties:
Buffer
CacheControl
Charset
ContentType
Expires
ExpiresAsolute
IsClientConnected
PICS
Status
Methods:
AddHeader
AppendToLog
BinaryWrite
Clear
End
Flush
Redirect
Write

Server Object
Properties:
ScriptTimeout
Methods:
CreateObject
HTMLEncode
MapPath
URLEncode

Session Object
Collections:
Contents
StaticObjects
Properties:
CodePage
LCID
SessionID
Timeout
Methods:
Abandon
Events:
Session_OnEnd
Session_OnStart


ActiveX Components

This section provides an overview of the ActiveX components included with Active Server Pages (ASP).

ActiveX components are designed to run on your Web server as part of a Web-based application. Components provide key functionality needed for Web applications, such as database access, so that you do not have to create and re-create the code to perform these tasks.

Database Access

You use the Database Access component to provide access to a database from within your Web application. You can then display the entire contents of a table, allow users to construct queries, and perform other database operations from Web pages.

Ad Rotator

You use the Ad Rotator component to alternately display a series of images, as well as to provide a link from the displayed image to another URL. You keep a list of advertisements in a text file; the Ad Rotator component displays them according to the statements in your data file.

Content Rotator

The Content Rotator component automates the rotation of HTML content strings on a Web page. Each time a user requests the Web page, the Content Rotator component displays a new HTML content string based upon information that you specify in a Content Schedule file.

Because the content strings can contain HTML tags, you can display any type of content that HTML can represent: text, images, or hyperlinks. For example, you can use this component to rotate through a list of daily quotations or hyperlinks, or to change your text and background colors each time the Web page is opened.

Browser Capabilities

With the Browser Capabilities component, you can tailor the content you send to a browser based on the browser's capabilities.

File Access

The File Access Component provides objects you can use to retrieve and modify files in a computer’s file system.

Content Linking

The Content Linking component makes it easy for you to provide logical navigation through the .asp files in an application. Rather than maintaining URL references in a number of .asp files, you can specify the sequential organization of .asp files in a single, easy-to-edit text file.

Collaboration Data Objects for Windows NT Server

The Collaboration Data Objects for NTS component provides messaging objects for use by Web applications. The library lets you quickly and easily add to your application the ability to send and receive mail items. You can create programmable messaging objects, then use their properties and methods to meet the needs of your application.

MyInfo, Status, System, and Tools

The MyInfo, Status, System, and Tools components provide compatibility for applications developed on the Macintosh and deployed on computers running Microsoft Windows.

  • The MyInfo component keeps track of personal information about the Web site owner, such as the name and address of the organization running the Web site, as well as Web site settings, such as whether the Web site has a guest book.
  • The Status component keeps track of information about your site, such as the number of visitors or the number of HTTP connections.
  • The System component creates a status object that has properties that contain server status information. Currently this server status is only available on Personal Web Server for Macintosh.
  • The Tools component provides methods to generate a random number, check for the existence of a file, or process an HTML form.

Page Counter

The Page Counter component counts and displays the number of times a Web page has been requested. At regular intervals it writes the number of hits to a text file so that in the event of a server shutdown, the data is not lost.

Permission Checker

The Permission Checker component tests the Web user's access rights to a file or a page. You can use the Permission Checker component to customize an ASP-based page for different types of users. For example, if a Web page contained hyperlinks, you could use the Permission Checker component to test the user's permissions for the corresponding Web pages and omit or make inactive any links to pages for which the user does not have access.


Writing Simple Scripts

An ASP script can perform a task as simple as displaying the value of a variable to one as complex as sending a SQL statement to a database. This section discusses common tasks that many script authors want to accomplish, such as processing the information returned by an HTML form or debugging a script. If you are new to scripting languages or simply new to ASP, you should review the topics in Using Scripting Languages to learn how to create an ASP page and the basic syntax of ASP commands.

This section contains:

  • Sending Content to the Browser: Explains how to control the pages returned to a browser.
  • Sending Scripts to the Browser: Explains how to use server scripts to create client scripts.
  • Including Files: Explains how to use the #include statement to insert the contents of a file into an ASP file.
  • Working with HTML Forms: Explains how to get the data from an HTML form.
  • Accessing a Database: Explains how to use the Database Access Component to retrieve information from a database.
  • Debugging ASP Scripts: Explains how to use the interactive debugger to find and eliminate errors in your scripts.
  • Interpreting ASP Error Messages: Describes the causes of common ASP errors.

This section does not contain information on:

  • Basic information on creating ASP pages and using ASP commands; see Using Scripting Languages.
  • More advanced tasks; see ASP Applications.
  • Reference pages for the ASP objects and components.


Sending Content to the Browser

As an ASP script is processed, any text or graphics not enclosed within ASP delimiters or <SCRIPT> tags is simply returned to the browser. You can also explicitly send content to the browser by using the Response object.

Sending Content

To send content to the browser from within ASP delimiters or from a procedure, use the Write method of the Response object. For example, the following statement sends a different greeting to the user depending on whether the user has visited the page before:

<%
If FirstTime = True Then
  Response.Write "<H3 ALIGN=CENTER>Welcome to the Overview Page</H3>"
Else
  Response.Write "<H3 ALIGN=CENTER>Welcome Back to the Overview Page</H3>"
End If
%>

Outside of a procedure, you do not have to use Response.Write to send content back to the user. Content that is not within scripting delimiters is sent directly to the browser, which formats and displays this content accordingly. For example, the following script produces exactly the same output as the previous script:

<H3 ALIGN=CENTER>
<% If FirstTime Then %>
Welcome to the Overview Page.
<% Else %>
Welcome Back to the Overview Page.
<% End If %>
</H3>

Use intermingled script commands and HTML when you just need to return output once or when it is more convenient to add statements to existing HTML text. Use Response.Write when you do not want to break up a statement with delimiters or when you want to build the string that is returned to the browser. For example, you could construct a string of text that builds a table row with values sent by an HTML form:

Response.Write "<TR><TD>" & Request.Form("FirstName") _
 & "</TD><TD>" & Request.Form("LastName") & "</TD></TR>"

Request.Form returns the values sent from an HTML form (see Working with HTML Forms). The ampersand character (&) is the string continuation character for VBScript.

Setting the Content Type

When the Web server returns a file to a browser, it tells the browser what type of content is contained in the file. This enables the browser to determine whether it can display the file itself or whether it has to call another application. For example, if the Web server returns a Microsoft Excel spreadsheet, the browser must be able to start a copy of Microsoft Excel to display the page. The Web server recognizes file types by mapping the file name extension to a list of MIME types.

You can use the ContentType property of the Response object to set the HTTP content type string for the content you send to a user. For example, the following command sets the content type for channel definitions:

<% Response.ContentType = "application/x-cdf" %>

For more information about channels, see “Creating Dynamic Channels,” in this topic.

Other common content types are text/plain (for content returned as text instead of interpreted HTML statements), text/gif (for GIF images), and video/quicktime (for movies in the Apple QuickTime® format). A set of standard MIME types has been defined; in addition, a Web server or Web browser may support custom MIME types. To see the content types supported by your Microsoft Web server, use Internet Service Manager to open the property sheets for your Web site, click the HTTP Headers tab, and then click the File Types tab.

Redirecting the Browser

Instead of sending content to a user, you can redirect the browser to another URL with the Redirect method. For example, if you want to make sure users have entered your application from a home page so that they receive a customer ID, you can check to see if they have a customer ID; if they do not, you can redirect them to the home page.

<%
If Session("CustomerID") = 0 Then
  Response.Redirect "homepage.asp"
End If
%>

Unless you have buffering turned on, you must redirect the browser before any content or headers are returned to the browser. Place the Response.Redirect statement at the top of the page, before the <HTML> tag, to ensure that nothing has been returned to the browser. If you use Response.Redirect after content or headers have been returned to the browser, you will see an error message.

If you want to use Response.Redirect from the middle of a page, use it along with the Response.Buffer property, as explained in the following section.

Buffering Content

By default, the Web server returns HTML and the results of processing scripts as it processes the ASP page. However, you can set the Buffer property of the Response object so that all of the server script commands on a page are processed before any content is sent to the user.

You can use buffering to determine at some point in the processing of a page that you do not want to send previous content to a user. You can, instead, redirect the user to another page with the Redirect method of the Response object, or clear the buffer with the Clear method of the Response object and send different content to the user. The following example uses both of these methods.

<%
'Turn on buffering.  This statement must appear before the <HTML> tag.
Response.Buffer = True %>
<html>
<body>
.
.
.
<%
If Request("FName") = "" Then
  Response.Clear
  Response.Redirect "/samples/test.html"
Else
  Response.Write Request("FName")
End If
%>
</body>
</html>

You could also use Response.Buffer to prevent the Web server from returning the HTTP header before a script can modify the header. Certain properties and methods, such as Response.Expires and Response.Redirect, modify the HTTP header.

When you set the Buffer property in a script and do not call the Flush method in the same script, the server will maintain Keep-Alive requests made by the client. The benefit of writing scripts in this manner is that server performance is improved because the server does not have to create a new connection for each client request (assuming that the server, client, and any proxy servers all support Keep-Alive requests). However, a potential drawback to this approach is that buffering prevents any of the response from being displayed to the user until the server has finished all script processing for the current .asp file. For long or complicated scripts, the user might be forced to wait a considerable amount of time before seeing the page.

Buffering is turned off by default for ASP applications. You can use Internet Service Manager to turn on buffering for an entire ASP application.

Allowing Proxy Servers to Cache Pages

Your application may be sending pages to a client through a proxy server. A proxy server acts on behalf of client browsers to request pages from Web sites. The proxy server caches HTML pages so that repeated requests for the same page can be returned quickly and efficiently to the browsers. Having the proxy server process requests and cache pages reduces the load on the network and on the Web server.

While caching works well for many HTML pages, it often does not work well for ASP pages that contain dynamically generated information. For example, pages that report stock market prices or display inventory for a high-volume business need to provide timely information. Information that is even one hour old might not be accurate enough. If your application returns personalized information, such as a custom home page, you want to ensure that no user sees another user's personal information.

By default, ASP instructs proxy servers not to cache the ASP page itself (although images, image maps, applets, and other items referenced from the page are cached). You can allow caching for certain pages by using the Response.CacheControl property to set the Cache-Control HTTP header field. The default value of Response.CacheControl is the string "Private", which prevents proxy servers from caching the page. To allow caching, set the Cache-Control header field to Public:

<% Response.CacheControl = "Public" %>

Because HTTP headers must be sent to the browser or proxy before any page content is sent, either put the Response.CacheControl property before any HTML tags or use Response.Buffer to buffer the page.

The Cache-Control header field is part of the HTTP 1.1 specification. ASP pages are not cached on proxies that support only HTTP 1.0 because no Expires header field is sent.

Preventing Browsers from Caching Pages

Each browser version has its own rules for determining whether to cache pages. To prevent a browser from caching ASP pages, use Response.Expires to set the Expires header:

<% Response.Expires = 0 %>

A value of 0 forces cached pages to expire immediately. Because HTTP headers must be sent to the browser before any page content is sent, either put the Response.Expires property before any HTML tags or use Response.Buffer to buffer the page.

Creating Dynamic Channels

Internet Explorer 4.0 introduces a new feature that Web designers can use to group Web pages with a common theme into channels. In the browser, channels are presented on a channel bar; users access a channel by clicking its icon. Channels are automatically updated in the background; users do not need to visit your site again to get the latest pages downloaded to their browsers. Channels provide a quick and intuitive way for users to see groups of related Web pages that are automatically updated.

Using ASP, you can write scripts to gather user preferences and then dynamically create channels. A channel definition file (.cdf) establishes the organization and scheduling of the channel contents. Commands in the .cdf file use a syntax similar to HTML tags, so they are easy to learn and to generate from a script. When you write an ASP script to create a channel definition file, give the script a .cdx extension. When ASP reads a file with a .cdx extension, it automatically sends the application/x-cdf content type, which tells the browser to interpret the bytes as channel definitions. If you do not use the .cdx extension, your script must manually set the content type to application/x-cdf by using Response.ContentType.

Here is an example of how you might use channels. The following HTML form asks the user to select channels. When submitted, the form calls a script in a .cdx file to create the channel definitions.

<P> Choose the channels you want. </P>
<FORM METHOD="POST" ACTION="chan.cdx">
<P><INPUT TYPE=CHECKBOX NAME=Movies> Movies
<P><INPUT TYPE=CHECKBOX NAME=Sports> Sports
<P><INPUT TYPE="SUBMIT" VALUE="SUBMIT">
</FORM>

The script in Chan.cdx builds the channel definitions based on the form values submitted with the request.

<% If Request.Form("Movies") <> "" Then %>
  <CHANNEL>
    channel definition statements for the movie pages
  </CHANNEL>
<% End If %>

<% If Request.Form("Sports") <> "" Then %>
  <CHANNEL>
    channel definition statements for the sports pages
  </CHANNEL>
<% End If %>

For information on channels and channel definition files, see the Internet Explorer page on microsoft.com (http://www.microsoft.com/ie). For more information on working with forms, see Working with HTML Forms. If you have installed the Exploration Air sample site, you can see an example of using ASP to create dynamic channels.

Sending Files to the Server

A browser can use the Posting Acceptor application to send files to the Web server. When Posting Acceptor uploads files, it sends URL-encoded form fields that list the name and location of each received file. You can add a postprocessing URL to the scripts that upload files to call an ASP script to process these field names. For example, you could write a script that automatically sends e-mail with the names and locations of the files to the system administrator.


Sending Scripts to the Browser

Although ASP is used primarily to create and process server-side scripts, you can extend its effectiveness by using it to generate client-side scripts which are then processed by the client browser. You can write server-side scripts that put together script commands that are sent to the browser.

You do this by combining client-side scripts that are enclosed by HTML comments with server-side scripts that are enclosed by delimiters:

<SCRIPT LANGUAGE="VBScript">
<!--
client script
<% server script  %>
client script
<% server script  %>
client script
...
-->
</SCRIPT>

With this functionality in your scripts, you can create exciting applications. For example, the following script will create several client-script subroutines that run on the user's Web browser.

<%
ServerTime = Time
ServerDate = Date

For i = 1 to 4
  Randomize
  GreetCondition = int(rnd * 3)
%>

<SCRIPT LANGUAGE="VBScript">
<!--

Sub ServeInfo<%= i %>()
  Select Case <%= GreetCondition%>
    Case 0
      Msg =  "Hello, the time is <%= ServerTime %>."
    Case 1
      Msg = "Welcome! Today's date is <%= ServerDate %>."
    Case 2
      Msg = "Hi, the time is <%= ServerTime %> and the date is <%= ServerDate %>.
  End Select
  Document.Write    Msg
End Sub

ServeInfo<%= i %>()

//-->
</SCRIPT>

<br>

<%
Next
 %>

In the previous script, ASP retrieves time and date information from the server, and then loops several times to create subroutines that execute on the user's Web server. Each of these client-side subroutines render a randomly selected greeting, displaying the time and date information.

Scripts of this kind can be expanded, for example, to retrieve and deliver configuration information to a special client-side script or component, such as an ActiveX control. Through clever use of this scripting technique, you can also reduce the amount of time that your Web server spends processing and returning user information requests.


Including Files

Server-side include directives give you a way to insert the content of another file into a file before the Web server processes it. ASP implements only the #include directive of this mechanism. To insert a file into an .asp file, Use the following syntax:

<!--#include virtual | file ="filename"-->

The virtual and file keywords indicate the type of path you are using to include the file, and filename is the path and file name of the file you want to include.

Included files do not require a special file name extension; however, it is considered good programming practice to give included files an .inc extension to distinguish them from other types of files.

Using the Virtual Keyword

Use the virtual keyword to indicate a path beginning with a virtual directory. For example, if a file named Footer.inc resides in a virtual directory named /Myapp, the following line would insert the contents of Footer.inc into the file containing the line:

<!--#include virtual ="/myapp/footer.inc"-->

Using the File Keyword

Use the file keyword to indicate a relative path. A relative path begins with the directory that contains the including file. For example, if you have a file in the directory Myapp, and the file Header1.inc is in Myapp\Headers, the following line would insert Header1.inc in your file:

<!--#include file ="headers/header1.inc"-->

Note that the path to the included file, Headers/header1.inc, is relative to the including file; if the script containing this #include statement is not in the directory /Myapp, the statement would not work.

You can also use the file keyword with ../ syntax to include a file from a parent, or higher-level, directory if the Enable Parent Paths option is selected in Internet Service Manager.

Location of Included Files

Included files can reside within a directory in your Web site or outside of your Web site. Generally, you should keep included files within Web site directories. If an included file resides within a directory in your Web site, changes to the included file appear the next time a browser requests the including file. If, however, the included file resides outside your Web site, changes will not appear until the ASP application is restarted or until the Web server is restarted. ASP detects changes to any including file that is contained in the application name space (under an application starting point directory).

Including Files: Tips and Cautions

An included file can, in turn, include other files. An .asp file can also include the same file more than once, provided that the #include directives do not cause a loop. For example, if the file First.asp includes the file Second.inc, Second.inc must not in turn include First.asp. Nor can a file include itself. ASP detects such loop or nesting errors, generates an error message, and stops processing the requested .asp file.

ASP includes files before executing script commands. Therefore, you cannot use a script command to build the name of an included file. For example, the following script would not open the file Header1.inc because ASP attempts to execute the #include directive before it assigns a file name to the variable name.

<!-- This script will fail -->
<% name=(header1 & ".inc") %>
<!--#include file="<%= name %>"-->

Scripts commands and procedures must be entirely contained within the script delimiters <% and %>, the HTML tags <SCRIPT> and </SCRIPT>, or the HTML tags <OBJECT> and </OBJECT>. That is, you cannot open a script delimiter in an including .asp file, then close the delimiter in an included file; the script or script command must be a complete unit. For example, the following script would not work:

<!-- This script will fail -->
<%
For i = 1 To n
  statements in main file
  <!--#include file="header1.inc" -->
Next
%>

The following script would work:

<%
For i = 1 to n
  statements in main file
%>
<!--#include file="header1.inc" -->
<% Next %>


Working with HTML Forms

Using the ASP Request object you can create simple, yet powerful scripts for collecting and processing data gathered with HTML forms. In this topic you will not only learn how to create basic form processing scripts, but also acquire useful techniques for validating form information, both on your Web server and at the user's browser.

About HTML Forms

HTML forms, the most common method for gathering Web information, are arrangements of special HTML tags that render user interface controls on a Web page. Text boxes, buttons, and check boxes are examples of controls that enable users to interact with a Web page and submit information to a Web server.

The following HTML example generates a form where a user can enter first name, last name, and age, and includes a button for submitting information to a Web server. The form also contains a hidden control (not rendered by the Web browser) that you can use to pass additional information to a Web server.

<FORM METHOD="POST" ACTION="myfile.asp">
<INPUT TYPE="text" NAME="firstname">
<INPUT TYPE="text" NAME="lastname">
<INPUT TYPE="text" NAME="age">
<INPUT TYPE="hidden" NAME="userstatus" VALUE= "new">
<INPUT TYPE="submit"  VALUE="Enter">
</FORM>

Processing Form Inputs with ASP

When a form submits information to the Web server, the user's Web browser requests the .asp file specified by the HTML <FORM > tag's ACTION attribute (in the previous example, this file was called Myfile.asp). The .asp file contains scripts that carry out form value processing, such as displaying a table of results or querying information from a database.

You can use .asp files to collect HTML form values in three ways:

  • A static .htm file can contain a form that posts its values to an .asp file.
  • An .asp file can create a form that posts information to another .asp file.
  • An .asp file can create a form that posts information to itself, that is, to the .asp file that contains the form.

The first two methods operate in the same way as forms that interact with other gateway programs, except that, with ASP, you can include commands that read and respond to user choices.

Creating an .asp file that contains a form definition that posts information to itself is a slightly more complicated but very powerful means of working with forms. This process is demonstrated in Verifying Form Input.

Getting Form Input

The ASP Request object provides two collections that greatly simplify the task of retrieving form information appended to a URL request.

QueryString Collection

The QueryString collection retrieves form values passed to your Web server as text following a question mark in the request URL. The form values can be appended to the request URL by using either the HTTP GET method or by manually adding the form values to the URL.

For example, if the previous form example used the GET method (ACTION = "GET") and the user typed Jeff, Smith, and 30, then the following URL request would be sent to the server:

http://scripts/Myfile.asp?firstname=Jeff&lastname=Smith&age=30&userstatus=new

Myfile.asp might contain the following form processing script:

Hello, <%= Request.QueryString("firstname") %>   <%= Request.QueryString("lastname") %>.
You are  <%= Request.QueryString("age") %>  years old.

<%
If Request.QueryString("userstatus")  = "new user" then
  Response.Write"This is your first visit to this Web site!"
End if
%>

In this case, your Web sever would return the following text to the user's Web browser:

Hello, Jeff Smith. You are 30 years old. This is your first visit to this Web site!

The QueryString collection also has an optional parameter that you can use to access one of multiple values that appear in the request body. You can also use the Count property to count the number of times that a specific type of value appears.

For example, a form containing a list box with multiple items can render the following request:

http://list.asp?food=apples&food=olives&food=bread

You could use the following command to count multiple values:

Request.QueryString("food").Count

To display the multiple values types, List.asp could contain the following script:

<%Total = Request.QueryString("food").Count%>
<%For i = 1 to Total%>
  <%= Request.QueryString("food")(i)  %> <BR>
<%Next%>
The preceding script would display:
apples
olives
bread

Form Collection

When you use the HTTP GET method to pass long and complex form values to a Web server, you run the risk of losing information. Most Web servers tend to restrict the size of the URL query string, so that lengthy form values passed with the GET method tend to get truncated. If you need to send a large amount of information from a form to a Web server, you must use the HTTP POST method. The POST method, which sends form data in the HTTP request body, can send a virtually unlimited number of characters to a server. You can use the ASP Request object's Form collection to retrieve the values sent with the POST method.

The Form collection stores values in a manner similar to the QueryString collection. For example, if a user filled out a form by entering a long list of names, then you could retrieve the names with the following script:

<% For i = 1 to Request.Form.Count %>
<% =Request.Form("names")(i) %>
<% Next %>

Verifying Form Input

A good form processing script validates the information entered into a form before processing data. A validation script can check whether the user has entered the correct type of information into a form. For example, if your Web site includes a form that lets users compute financial information, you may want to verify that users have actually entered numerical information, and not text, before processing results.

A particularly advantageous way of verifying form input is to create a form that posts information to itself. In this case, the .asp file contains the form that retrieves information. For example, the following script determines whether a user entered a number into the "age" form field, by posting information to itself:

<% If Isnumeric(Request.QueryString("Age")) then %>
  <p>Hello, your age is <%=Request.QueryString("age")%>
<%Else %>
  <p>Please enter a numerical age.
<%End If %>

<FORM METHOD= "POST"  ACTION="verify.asp"  >
Name: <INPUT TYPE="text" NAME="Name" >
Age:  <INPUT TYPE="text" NAME="Age" >
<INPUT TYPE="submit" VALUE="Enter">
</FORM>

In this example, the script is in a file named Verify.asp, the same file which contains the form. The form posts information to itself by specifying Verify.asp in the ACTION attribute.

You can also create client-side scripts that check whether a user has entered the appropriate information. In addition to prompting users more quickly about form entry errors, verifying form input at the user's Web browser can reduce your Web server's network traffic. The following script runs on the user's Web browser and validates user information before submitting information to your Web server.

<SCRIPT LANGUAGE="VBScript">
<!--
Sub btnEnter_OnClick
  Dim TheForm
  Set TheForm = Document.MyForm
  If IsNumeric(TheForm.Age.Value) Then
    TheForm.submit
  Else
    Msgbox "Please enter a numerical age."
  End if
End Sub
//-->
</SCRIPT>

<FORM  METHOD= "POST" NAME= MyForm  ACTION="myfile.asp"  >
Name: <INPUT TYPE="text" NAME="Name" >
Age:  <INPUT TYPE="text" NAME="Age" >
<INPUT TYPE="button" NAME="btnEnter"  VALUE="Enter">
</FORM>


Accessing a Database

ActiveX Data Objects (ADO) are an easy-to-use yet extensible technology for adding database access to your Web pages. You can use ADO to write compact and scalable scripts for connecting to Open Database Connectivity (ODBC) compliant databases and OLE DB compliant data sources. If you are a scripter with a modest understanding of database connectivity, you will find ADO's command statements uncomplicated and approachable. Likewise, if you are an experienced database programmer you will appreciate ADO's advanced, language neutral connection and query manipulation features.

Creating an ODBC Data Source Name File

Before creating database scripts you need to provide a way for ADO to locate, identify, and communicate with your database. Database drivers – programs that pass information from your Web application to a database – use a Data Source Name (DSN) to locate and identify a particular ODBC compliant database. Typically, the DSN contains database configuration, user security, and location information, and can take the form of an entry in the Windows NT registry or a text file.

With ODBC you can choose the type of DSN you wish to create: User, System, or File. The User and System DSN reside in the Windows NT registry. The System DSN enables all users logged on to particular server to access a database, while the User DSN limits database connectivity to a specific user with appropriate security credentials. The File DSN, which takes the form of text file, provides access to multiple users and is easily transferable from one server to another by copying DSN files. For these reasons, the examples in this topic will use the File DSN.

You can create a file based DSN by opening Control Panel from the Windows Start menu. Double-click the ODBC icon, and then select the File DSN property sheet. Click Add, choose your database's driver, and then click Next. Follow the proceeding instructions for configuring a DSN for your particular database software.

To configure a Microsoft Access Database File DSN
  1. In the Create New Data Source dialog box, select Microsoft Access Driver from the list box, then click Next.
  2. Type in a name for your DSN file, then click Next.
  3. Click Finish to create the data source.
  4. On the ODBC Microsoft Access 97 Setup dialog box, click Select. Choose a Microsoft Access database file (*.mdb), then click OK.

Note For performance and reliability reasons, it is strongly recommend that you use a client-server database engine for the deployment of data driven Web applications that require high-demand access from more than 10 concurrent users. Although Active Server Pages works with any ODBC-compliant database, it has been extensively tested and is designed to work with client server databases such as Microsoft ® SQL Server ™ or Oracle.

ASP supports shared file databases (Microsoft ® Access or Microsoft ® FoxPro) as valid data sources. Although some examples in the ASP documentation use a shared file database, it is recommended that these types of database engines be used only for development purposes or limited deployment scenarios. Shared file databases may not be as well suited as client-server databases for very high-demand, production-quality Web applications.

To configure a SQL Server Database File DSN

Note If the database resides on a remote server, contact the server administrator for additional configuration information; the following procedure uses the ODBC default settings for SQL Server, which may not work for your hardware configuration.

  1. On the Create New Data Source dialog box, select SQL Server from the list box, then click Next.
  2. Type in a name for your DSN file, then click Next.
  3. Click Finish to create the data source.
  4. Type in the name of the server running SQL Server, your login ID, and your password.
  5. On the Create a New Data Source to SQL Server dialog box, type the name of the server containing the SQL Server database in the Server list box, then click Next.
  6. Select a method for verifying Login ID authenticity.
  7. If you choose SQL Server authentication, enter a login ID and password, then click Next.
  8. In the Create a New Data Source to SQL Server dialog box, set your default database, driver stored procedure settings, and ANSI identifiers, then click Next. (For more information, click Help.)
  9. In the dialog box (also named Create a New Data Source to SQL Server), choose a character translation method, then click Next. (For more information, click Help.)
  10. In the next dialog box (also named Create a New Data Source to SQL Server), select logging options.

    11. Note Typically, you should only use logging for debugging database access problems.

  11. On the ODBC Microsoft SQL Server Setup dialog box, click Test Data Source. If the DSN was created correctly, the Test Results dialog box will indicate that testing was completed successfully.

    12. SQL Server Connection and Security Information

    If you are developing an ASP database application intended to connect to a remote SQL Server database you should also be aware of the following issues:

    • Connection scheme- You can choose between the TCP/IP Sockets and Named Pipes methods for accessing a remote SQL Server database. With Named Pipes, database clients must be authenticated by Windows NT before establishing a connection, raising the possibility that a remote computer running named pipes might deny access to a user who has the appropriate SQL Server access credentials, but does not have a Windows NT user account on that computer. Alternatively, connections using TCP/IP Sockets connect directly to the database server, without connecting through an intermediary computer – as is the case with Named Pipes. And because connections made with TCP/IP Sockets connect directly to the database server, users can gain access through SQL Server authentication, rather than Windows NT authentication.

      • Note To improve performance when connecting to a remote databases, use TCP/IP Sockets.

    • Security - If you use SQL Server's Integrated or Mixed security features, and the SQL Server database resides on a remote server, you will not be able to use Windows NT Challenge/Response authentication. Specifically, you cannot forward Windows NT Challenge/Response credentials to the remote computer. This means that you may have to use Basic authentication, which relies on the user to provide user name and password information.

    For more information about these issues, visit the Microsoft SQL Server Technical Support Home Page at http://www.microsoft.com/sqlsupport/.

To configure an Oracle Database File DSN

Make sure that the Oracle client software is correctly installed on the computer where you intend to create the DSN. Consult your server administrator and database software documentation for more information.

  1. On the Create New Data Source dialog box, select Microsoft ODBC for Oracle from the list box, then click Next.
  2. Type in a name for your DSN file, then click Next.
  3. Click Finish to create the data source.
  4. Enter a user name, password, and server name, then click OK.

Note DSN files have a .dsn extension and reside in the \Programs\Common Files\ODBC\Data Sources directory.

For more information about creating a DSN file, visit the Microsoft ODBC Web site at http://microsoft.com/odbc/.

Connecting to a Database

The very first step in accessing database information is establishing a connection with the database source. ADO provides the Connection object which you can use for establishing and managing connections between your applications and ODBC databases. The Connection object features a variety of properties and methods which you can use to open and close database connections, and to issue queries for updating information.

To establish a database connection, you first create an instance of the Connection object. For example, the following script instantiates the Connection object and proceeds to open a connection:

<%
  'Create a connection object
  Set cn = Server.CreateObject("ADODB.Connection")
  'Open a connection; the string refers to the DSN
  cn.Open  "FILEDSN=MyDatabase.dsn"
%>

Note The DSN string does not contain spaces, either, before or after the equal sign (=).

In this case, the Connection object's Open method refers to the file based DSN, containing location and configuration information about the database. Optionally, you can also refer directly to an explicit provider, data source, user ID, and password, rather than to a DSN.

Executing Queries with the Connection Object

With the Connection object's Execute method, you can issue Structured Query Language (SQL) queries to the database source and retrieve results. SQL, an industry standard language for communicating with databases, has commands for retrieving and updating information.

The following script uses the Connection object's Execute method to issue a query in the form of a SQL INSERT command, which inserts data into a specific database table. In this case, the script block inserts the name Jose Lugo into a database table named Customers.

<%
  'Define  file based DSN
  strDSN = "FILEDSN=MyDatabase.dsn"

  'Instantiate the Connection object and open a database connection
  Set cn = Server.CreateObject("ADODB.Connection")
  cn.Open strDSN

  'Define SQL SELECT statement
  strSQL = "INSERT INTO Customers (FirstName, LastName) VALUES ('Jose','Lugo')"
  'Use the Execute method to issue a SQL query to database
  cn.Execute(strSQL)

%>

Note The file based DSN path string should not include spaces before and after the equal sign (=).

In addition to the SQL INSERT command, you can use the SQL UPDATE and DELETE commands to change and remove database information.

With the SQL UPDATE command you can change the values of items in a database table. The following script uses the UPDATE command to change the Customers table's FirstName fields to Jeff for every LastName field containing the last name Smith.

<%
  Set cn = Server.CreateObject("ADODB.Connection")
  cn.Open "FILEDSN=MyDatabase.dsn"
  cn.Execute "UPDATE Customers SET FirstName = 'Jeff' WHERE LastName = 'Smith' "
%>

To remove specific records from a database table, use the SQL DELETE command. The following script removes all rows from the Customers table where the last name is Smith:

<%
  Set cn = Server.CreateObject("ADODB.Connection")
  cn.Open "FILEDSN=MyDatabase.dsn"
  cn.Execute "DELETE FROM Customers WHERE LastName = 'Smith'"
%>

Note You must be careful when using the SQL DELETE command. A DELETE command without an accompanying WHERE clause will delete all rows from a table. Be sure to include a SQL WHERE clause, which specifies the exact rows to be deleted.

Using the Recordset Object for Manipulating Results

Although the Connection object simplifies the task of connecting to a database and issuing a query, the Connection object has limitations. Specifically, you cannot create scripts with the Connection object that retrieve and display data database information; rather, you must know exactly what changes you want to make to a database and then implement the changes through use of a query.

For retrieving data, examining results, and making changes to your database, ADO provides the Recordset object. As its name implies, the Recordset object has features that you can use, depending on your query constraints, for retrieving and displaying a set of database rows, or records. The Recordset object maintains the position of each record returned by a query, thus enabling you to "step" through results one item at a time.

Depending on how you configure the Recordset object's cursor type properties, you can scroll through and update records. Database cursors behave like pointers that let you locate a specific item in a set of records. Cursors are especially useful for retrieving and inspecting records, and then carrying out an operation based on those records. The Recordset object has properties that enable you to precisely control the behavior of cursors, improving your ability to inspect and update results. For example, you can use the CursorType and CursorLocation properties to configure a cursor type that returns a result set to your client application (results normally remain on the database server) and displays the latest changes to a database made by other users.

Retrieving a Record Set

Successful database applications employ both the Connection object, to establish a link, and the Recordset object, to manipulate returned data. By "teaming up" the specialized functions of both objects you can develop database applications to carry out almost any data handling task. For example, the following server-side script uses the Recordset object to execute a SQL SELECT command. The SELECT command retrieves a specific set of information based on query constraints. The query also contains a SQL WHERE clause, used to narrow down a query to a specific criterion. In this example, the WHERE clause limits the query to all records containing the last name Smith from the Customers database table.

<%
  'Establish a connection with data source
  strDSN  = "FILEDSN=MyDatabase.dsn"
  Set cn = Server.CreateObject("ADODB.Connection")
  cn.Open strDSN

  'Instantiate a Recordset object
  Set rsCustomers = Server.CreateObject("ADODB.Recordset")

  'Open a recordset using the Open method
  ' and use the connection established by the Connection object
  strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName = 'Smith' "
  rsCustomers.Open  strSQL, cn

  'Cycle through record set and display the results
  ' and increment record position with MoveNext method
   Set objFirstName = rsCustomers("FirstName")
   Set objLastName = rsCustomers("LastName")
   Do Until rsCustomers.EOF
   Response.Write objFirstName & " " & objLastName & "<BR>"
   rsCustomers.MoveNext
   Loop

%>

Notice that in the previous example, the Connection object established the database connection and the Recordset object used the same connection to retrieve results from the database. This method is advantageous when you need to precisely configure the way in which the link with the database is established. For example, if you needed to specify the time delay before a connection attempt aborts, you would need to use the Connection object to set this property. However, if you just wanted to establish a connection using ADO's default connection properties, you could use Recordset object's Open method to establish a link:

<%
  strDSN  = "FILEDSN=MyDatabase.dsn"
  strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName = 'Smith' "
  Set rsCustomers = Server.CreateObject("ADODB.Recordset")

  'Open a connection using the Open method
  'and use the connection established by the Connection object
  rsCustomers.Open  strSQL, strDSN

  'Cycle through the record set, display the results,
  ' and increment record position with MoveNext method
   Set objFirstName = rsCustomers("FirstName")
   Set objLastName = rsCustomers("LastName")
   Do Until rsCustomers.EOF
      Response.Write objFirstName & " " & objLastName & "<BR>"
   rsCustomers.MoveNext
   Loop
%>

When you establish a connection using the Recordset object's Open method to establish a connection, you are implicitly using the Connection object to secure the link.

Improving Queries with the Command Object

With the ADO Command object you can execute queries in the same way as queries executed with the Connection and Recordset object, except that with the Command object you can prepare, or compile, your query on the database source and then repeatedly reissue the query with a different set of values. The benefit of compiling queries in this manner is that you can vastly reduce the time required to reissue modifications to an existing query. In addition, you can leave your SQL queries partially undefined, with the option of altering portions of your queries just prior to execution.

The Command object's Parameters collection saves you the trouble of reconstructing your query each time you want to reissue your query. For example, if you need to regularly update supply and cost information in your Web based inventory system, you can predefine your query in the following way:

<%
 'Open a connection using Connection object Command object
 'does not have an Open method for establishing a connection
 strDSN = "FILEDSN=MyDatabase.dsn"
 Set cn = Server.CreateObject("ADODB.Connection")
 cn.Open strDSN

 'Instantiate Command object; use ActiveConnection property to attach
 'connection to Command object
 Set cm= Server.CreateObject("ADODB.Command")
 Set cm.ActiveConnection = cn

 'Define SQL query
 cm.CommandText = "INSERT INTO Inventory (Material, Quantity) VALUES (?, ?)"

 'Save a prepared (or pre-compiled) version of the query specified in CommandText
 'property before a Command object's first execution.
 cm.Prepared = True

 'Define query parameter configuration information
 cm.Parameters.Append cm.CreateParameter("material_type",200, ,255 )
 cm.Parameters.Append cm.CreateParameter("quantity",200, ,255 )

 'Define and execute first insert
 cm("material_type") = "light bulbs"
 cm("quantity") = "40"
 cm.Execute

 'Define and execute second insert
 cm("material_type") = "fuses"
 cm("quantity") = "600"
 cm.Execute
%>

Examining the previous example, you will notice that the script repeatedly constructs and reissues a SQL query with different values, without having to redefine and resend the query to the database source. Compiling your queries with the Command object also offers you the advantage of avoiding problems that can arise from concatenating strings and variables to form SQL queries. In particular, by using the Command object's Parameter collection, you can avoid problems related to defining certain types of string, date, and time variables. For example, SQL query values containing apostrophes (') can cause a query to fail:

  strSQL = "INSERT INTO Customers (FirstName, LastName) VALUES ('Robert','O'Hara')"

Notice that the last name O'Hara contains an apostrophe which conflicts with the apostrophes used to denote data in the SQL VALUES keyword. By binding the query value as a Command object parameter, you avoid this type of problem.

Combining HTML Forms and Database Access

Web pages containing HTML forms can enable users to remotely query a database and retrieve specific information. With ADO you can create surprisingly simple scripts that collect user form information, create a custom database query, and return information to the user. Using the ASP Request object, you can retrieve information entered into an HTML form and incorporate this information into your SQL statements. For example, the following script block inserts information supplied by an HTML form into a table. The script collects the user information with the Request object 's Form collection.

<%
 'Open a connection using Connection object. The Command object
 'does not have an Open method for establishing a connection
 strDSN = "FILEDSN=MyDatabase.dsn"
 Set cn = Server.CreateObject("ADODB.Connection")
 cn.Open strDSN

 'Instantiate Command object
 'and  use ActiveConnection property to attach
 'connection to Command object
 Set cm= Server.CreateObject("ADODB.Command")
 Set cm.ActiveConnection = cn

 'Define SQL query
 cm.CommandText = "INSERT INTO MySeedsTable (Type) VALUES (?)"

 'Define query parameter configuration information
 cm.Parameters.Append cm.CreateParameter("type",200, ,255 )

 'Define and execute insert
 cm("type") = Request("SeedType")
 cm.Execute

%>

For more information about forms and using the ASP Request object, see Working with HTML Forms.

Managing Database Connections

One of the main challenges of designing a sophisticated Web database application, such as an online order entry application servicing thousands of customers, is properly managing database connections. Opening and maintaining database connections, even when no information is being transmitted, can severely strain a database server's resources and result in connectivity problems. Well designed Web database applications recycle database connections and compensate for delays due to network traffic.

Timing Out a Connection

A database server experiencing a sudden increase in activity can become backlogged, greatly increasing the time required to establish a database connection. As a result, excessive connection delays can reduce the performance of your database application.

With the Connection object's ConnectionTimeout you can limit the amount of time that your application waits before abandoning a connection attempt and issuing an error message. For example, the following script sets the ConnectionTimeout property to wait twenty seconds before cancelling the connection attempt:

Set cn = Server.CreateObject("ADODB.Connection")
cn.ConnectionTimeout = 20
cn.Open "FILEDSN=MyDatabase.dsn"

The default for the ConnectionTimeout property is 30 seconds.

Note Before incorporating the ConnectionTimeout property into you database applications, make sure that your connection provider and data source support this property.

Pooling Connections

Web database applications that frequently establish and terminate database connections can reduce database server performance. ASP supports efficient connection management by using the connection pooling feature of ODBC 3.5. Connection pooling maintains open database connections and manages connection sharing across different user requests to maintain performance and to reduce the number of idle connections. On each connection request, the connection pool first determines if there is an idle connection in the pool. If so, the connection pool returns that connection instead of making a new connection to the database.

If you want your ODBC driver to participate in connection pooling you must configure your specific database driver and then set the driver's CPTimeout property in the Windows NT registry. When ODBC disconnects a connection, the connection is saved in a pool, rather that disconnected. The CPTimeout property determines the length of time that a connection remains in the connection pool. If the connection remains in the pool longer than the duration set by CPTimeout, the connection is closed and removed from the pool. The default value for CPTimeout is 60 seconds.

You can selectively set the CPTimeout property to enable connection pooling for a specific ODBC database driver by creating a registry key with the following settings:

\HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\driver-name\CPTimeout = timeout
 (REG_SZ, units are in seconds)

For example, the following key sets the connection pool timeout to 180 seconds (3 minutes) for the SQL Server driver.

\HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\SQL Server\CPTimeout = 180

Note By default, your Web server activates connection pooling for SQL Server by setting CPTimeout to 60 seconds.

Using Connections Across Multiple Pages

Although you can reuse a connection across multiple pages by storing the connection in ASP's Application object, doing so may unnecessarily keep open a connection open, defeating the advantages of using connection pooling. If you have many users that need to connect to the same ASP database application, a better approach is to reuse a database connection string across several Web pages by placing the string in ASP's Application object. For example, you can specify a connection string in the Global.asa file's Application_OnStart event procedure, such as in the following script:

Application.lock
Application("ConnectionString") = "FILEDSN=MyDatabase.dsn"
Application.unlock

Then in each ASP file that accesses the database, you can write:

<OBJECT RUNAT=Server ID=cn PROGID="ADODB.Connection"> </OBJECT>

to create an instance of the connection object for the page, and use the script:

cn.Open Application("ConnectionString")

to open the connection. At the end of the page, you close the connection with:

cn.Close
In the case of an individual user who needs to reuse a connection across multiple Web pages, you may find it more advantageous to use the Session object rather than the Application object for storing the connection string.

Closing Connections

To make the best use of connection pooling, explicitly close database connections as soon as possible. By default, a connection terminates after your script finishes execution. However, by explicitly closing a connection in your script after it is no longer needed, you reduce demand on the database server and make the connection available to other users.

You can use Connection object's Close method to explicitly terminate a connection between the Connection object and the database. The following script opens and closes a connection:

<% strDSN = "FILEDSN=MyDatabase.dsn"
Set cn = Server.CreateObject("ADODB.Connection")
cn.Open
cn.Close
%>


Debugging ASP Scripts

Regardless of your planning or level of experience, script errors, or bugs, may initially prevent your ASP server-side scripts from working correctly. This means that debugging, or the process of finding and correcting scripting errors, is crucial for developing successful and robust ASP applications.

The Microsoft Script Debugger Tool

The Microsoft® Script Debugger is a powerful debugging tool that can help you quickly locate bugs and interactively test your server-side scripts. With the Script Debugger, which also works with Windows Internet Explorer version 3.0 or later, you can:

  • Run your server-side scripts one line at a time.
  • Open a command window to monitor the value of variables, properties, or array elements, during the execution of your server-side scripts.
  • Set pauses to suspend execution of your server-side scripts (using either the debugger or a script command) at a particular line of script.
  • Trace procedures while running your server-side script.

Note You can use the debugger to view scripts and locate bugs, but not to directly edit your scripts. To fix bugs, you must edit your script with an editing program, save your changes, and run the script again.

(This feature is not available for Windows 95, or later versions.)

Enabling Debugging

Before you can begin debugging your server-side scripts, you must first configure your Web server to support ASP debugging.

After enabling Web server debugging, you can use either of the following methods to debug your scripts:

  • Manually open the Microsoft Script Debugger to debug your ASP server-side scripts.
  • Use Internet Explorer to request an .asp file. If the file contains a bug or an intentional statement to halt execution, the Microsoft Script Debugger will automatically start, display your script, and indicate the source of the error.

Scripting Errors

While debugging your server-side scripts you might encounter several types of errors. Some of these errors can cause your scripts to execute incorrectly, halt the execution of your program, or return incorrect results.

Syntax Errors

A syntax error is a commonly encountered error that results from incorrect scripting syntax. For example, a misspelled command or an incorrect number of arguments passed to a function generates an error. Syntax errors can prevent your script from running.

Run-Time Errors

Run-time errors occur after your script commences execution and result from scripting instructions that attempt to perform impossible actions. For example, the following script contains a function that divides a variable by zero (an illegal mathematical operation) and generates a run-time error:

<script language = "VBScript" runat = server>
  Result = Findanswer(15)
  document.write ("The answer is " &Result)

  Function Findanswer(x)
  'This statement generates a run-time error.
   Findanswer = x/0
  End Function
</script>

Bugs that result in run-time errors must be corrected for your script to execute without interruption.

Logical Errors

A logicalerror can often be the most insidious and difficult bug to detect. With logical errors, which arise from typing mistakes or flaws in programmatic logic, your script runs successfully, but yields incorrect results. For example, a server-side script intended to sort a list of values may return an inaccurate ordering if the script contains a > sign for comparing values, when it should have used a < sign.

Error Debugging Techniques

You can use several different debugging techniques to locate the source of bugs and to test your applications.

Just-In-Time (JIT) Debugging

When a run-time error interrupts execution of your ASP script, the Microsoft Script Debugger automatically starts, displays the .asp file with a statement pointer pointing to the line that caused the error, and generates an error message. With this type of debugging, called Just-In-Time (JIT) debugging, your computer suspends further execution of the program. You must correct the errors with an editing program and save your changes before you can resume running the script.

Breakpoint Debugging

When an error occurs and you cannot easily locate the source of the error, it is sometimes useful to preset a breakpoint. A breakpoint suspends execution at a specific line in your script. You can set one or many different breakpoints before a suspect line of script and then use the debugger to inspect the values of variables or properties set in the script. After you correct the error, you can clear your breakpoints so that your script can run uninterrupted.

To set breakpoints, open your script with the Microsoft Script Debugger and set a breakpoint. Then use your Web browser to request the script again. After executing the lines of script up to the breakpoint, your computer starts the Script Debugger, which displays the script with a statement pointer pointing to the line where you set the breakpoint.

VBScript Stop Statement Debugging

You can also add breakpoints to your server-side scripts written in VBScript by inserting a Stop statement at a location before a questionable section of server-side script. For example, the following ASP script contains a Stop statement that suspends execution before the script displays a result:

<%
  dayvalue = 3
  TheDay  =  WeekDayName(dayvalue)
  Stop			'set breakpoint here.
  Response.Write("Today is " + TheDay)
%>

When you request the previous script using your Web browser, the debugger starts and automatically displays the .asp file with the statement pointer indicating the location of the stop statement. Remember to remove Stop statements from production .asp files.

JScript Debugger Statement Debugging

To add breakpoints to your server-side scripts written in Microsoft® JScript, insert a debugger statement before a suspect line of script. For example, the following script includes a debugger statement that interrupts execution and automatically starts the Microsoft Script Debugger each time the script loops through a new value.

<%@ Language="JScript"  %>
<%
  for (var count = 1; count <= 10; count++)  {
    var eventest = count%2;
    debugger						    //Sets breakpoint
    if (eventest == 0) {
      response.write("Even value is " + count + "<br>")
    }
  }
%>

Remember to remove debugger statements from production .asp files.

Note Do not confuse the debugger statement with the JScript break statement. The break statement exits a currently running loop during execution and does not activate the Microsoft Script Debugger, nor pause execution.

Tips for Debugging Scripts

Aside from the Script Debugger, a good set of debugging tips can greatly reduce the amount of time you spend investigating the source of scripting errors. Although most bugs result from obvious sources, mispelled commands or missing variables, certain types of logic and execution errors can arise from considerably less evident sources.


ASP Applications

This section contains topics that apply to ASP applications.

This section contains:

  • About ASP Applications: Explains what an ASP application is.
  • Managing Applications: Explains how to start and stop applications and introduces some application management services.
  • Managing Sessions: Explains how to preserve information about a user.
  • Securing an ASP Application: Explains how to secure an application by verifying a user's identity and by controlling access to files in an application.
  • Creating a Transactional Script: Explains how to run a script under a transaction context.
  • Working with Multilanguage Sites: Explains how to set the code page (character encoding) and locale format for your application.
  • Writing Cross-Platform Applications: Explains how to write applications on a Macintosh that can be deployed on Windows NT.

This section does not contain information on:

  • Reference pages for the built-in ASP objects
  • Reference pages for the components that come with ASP
  • Building your own ASP components
  • Reference pages for VBScript
  • Reference pages for JScript
  • Sample scripts provided with the SDK Developer Samples


About ASP Applications

An ASP-based application is a collection of ASP pages and ActiveX components. When you define an application, you use Internet Service Manager to designate the application's starting-point directory in your Web site. Every file and folder under the starting-point directory in your Web site is considered part of the application until another starting-point directory is found. You thus use directory boundaries to define the scope of an application. You can have more than one application per Web site, and each application be configured differently.


Managing Applications

The Windows NT Option Pack provides services for managing ASP applications on the Web server. For example, Internet Service Manager gives the application developer an easy-to-use administration tool to set application properties. In addition, Active Server Pages provides scripting features that enable your applications to store global data. This topic briefly introduces some of these application management features and provides links to more detailed information.

Starting and Ending an Application

An application starts the first time the Web server receives a request for an ASP page in that application. An application ends when the Web server is shut down or when you stop an application using the Unload button in Internet Service Manager. You can only use the Unload button on applications that are running in a separate memory space (isolated) from the Web server process.

Isolating an Application

ASP applications normally run in the same memory space, or process, as the Web server. While this improves the performance of an ASP application, it places the Web server process at risk if the application fails. You can isolate an application by running it in a separate memory space from the Web server. If the ASP application fails, other applications and the Web server itself are protected.

Using Application State

When you are writing applications, you may need to make information pertaining to an application available to all users of the application. For example, you might want to create variables that enable system administrators to customize an application for their site by setting a different greeting or changing the title font on all ASP pages. These changes will be seen by any user who visits the site.

You can make data available to all users of an application from all pages of an application in several ways. The most frequently used is to give a variable or an object instance application scope by storing it in the ASP Application object. Application scope is useful for global data, such as a global counter, or global application configuration information, such as information stored in the registry or metabase. To learn how to give variables application scope, see Using Variables. To learn how to give objects application scope, see Setting Object Scope.

You may also need to write scripts that are run whenever an application starts up or shuts down.


Managing Sessions

One of the challenges to developing a successful Web application is maintaining user information over the course of a visit, or session, as the user jumps from page to page in an application. HTTP is a stateless protocol, meaning that your Web server treats each HTTP request for a page as an independent request; the server retains no knowledge of previous requests, even if they occurred only seconds prior to a current request. This inability to remember previous requests means that it is this difficult to write applications, such as an online catalog, where the application may need to track the catalog items a user has selected while jumping between the various pages of the catalog.

ASP provides a unique solution for the problem of managing session information. Using the ASP Session object and a special user ID generated by your server, you can create clever applications that identify each visiting user and collect information that your application can then use to track user preferences or selections.

ASP assigns the user ID by means of an HTTP cookie, which is a small file stored on the user's browser. So, if you are creating an application for browsers that do not support cookies, or if your customers might set their browsers to refuse cookies, you should should not use the ASP's session management features.

You may also need to write scripts that are run whenever an application starts up or shuts down.

Starting and Ending Sessions

A session can begin in three ways:

  • A new user requests a URL that identifies an .asp file in an application, and the Global.asa file for that application includes a Session_OnStart procedure.
  • A user stores a value in the Session object.
  • A user requests an .asp file in an application, and the application’s Global.asa file uses the <OBJECT> tag to instantiate an object with session scope. See Using Components for more information about using the <OBJECT> tag to instantiate an object.

A session automatically ends if a user has not requested or refreshed a page in an application for a specified period of time. This value is 20 minutes by default. You can change the default for an application by setting the Session Timeout property on the Application Options property sheet in Internet Service Manager. Set this value according to the requirements of your Web application and the memory capacity of your server. For example, if you expect that users browsing your Web application will linger on each page for only a few minutes, then you may want to significantly reduce the session timeout value from the default. A long session timeout period can result in too many open sessions, which can strain your server's memory resources.

If, for a specific session, you want to set a timeout interval that is shorter than the default application timeout, you can also set the Timeout property of the Session object. For example, the following script sets a timeout interval of 5 minutes.

<%  Session.Timeout = 5  %>

You can also set the timeout interval to be greater than the default value, the value determined by the Session Timeout property.

You can also explicitly end a session with the Abandon method of the Session object. For example, you can provide a Quit button on a form with the ACTION parameter set to the URL of an .asp file that contains the following command.

<% Session.Abandon %>

About SessionID and Cookies

The first time a user requests an .asp file within a given application, ASP generates a SessionID. A number produced by a complex algorithm, the SessionID uniquely identifies each user's session. At the beginning of a new session, the server stores the Session ID in the user's Web browser as a cookie.

The SessionID cookie is similar to a locker key in that, as the user interacts with an application during a session, ASP can store information for the user in a "locker" on the server. The user's SessionID cookie, transmitted in the HTTP request header, enables access to this information in the way that a locker key enables access to a locker's contents. Each time that ASP receives a request for a page, it checks the HTTP request header for a SessionID cookie.

After storing the SessionID cookie in the user's browser, ASP reuses the same cookie to track the session, even if the user requests another .asp file, or requests an .asp file running in other application. Likewise, if the user deliberately abandons or lets the session timeout, and then proceeds to request another .asp file, ASP begins a new session using the same cookie. The only time a user receives a new SessionID cookie is when the server administrator restarts the server, thus clearing the SessionID settings stored in random access memory, or the user restarts the Web browser.

By reusing the SessionID cookie, ASP minimizes the number of cookies sent to your browser. Additionally, if you determine that your ASP application does not require session management, you can prevent ASP from tracking session and sending SessionID cookies to users.

ASP will not send the session cookies under the following conditions:

  • Applications with the session state disabled.
  • An ASP page is defined as sessionless, that is, a page containing the <%@ EnableSessionState=False %> tag. For more information, see Sessionless ASP Pages.

You should also note that SessionID cookies are not intended to provide a permanent means for tracking users across multiple visits to a Web site. The SessionID information stored in the server computer's memory can be easily lost. If you want track users who visit your Web application over a longer periods, you must create a user identification by storing a special cookie in a user's Web browser and saving the cookie information to database. For more information, see Using Cookies.

Storing Data in the Session Object

The Session object provides a dynamic, associative array into which you can store information. You can store scalar variables and object variables into the Session object.

To store a variable in the Session object, assign a value to a named entry in the Session object. For example, the following command stores two new variables in the Session object:

<%
Session("FirstName") = "Jeff"
Session("LastName") = "Smith"
%>

To retrieve information from the Session object, access the named entry. For example, to display the current value of Session("FirstName"):

Welcome <%= Session("FirstName") %>

You can store user preferences in the Session object, and then access that preference to determine what page to return to the user. For example, you can allow a user to specify a text-only version of your content in the first page of the application and apply this choice on all subsequent pages that the user visits in this application.

<% If Session("ScreenResolution") = "Low" Then %>
This is the text version of the page.
<% Else %>
This is the multimedia version of the page.
<% End If %>

You can also store an object instance in the Session object, although doing so can affect server performance. For more information, see Setting Object Scope.

Managing Sessions for Web Farms

ASP session information is stored on the Web server. A browser must request pages from the same Web server for scripts to access session information. On Web farms (where many Web servers share the responsibility for responding to user requests) user requests will not always be routed to the same server. Instead, special software distributes all requests for the site URL to whichever server is free, a process called load balancing. Load balancing makes it difficult to maintain session information on a Web farm.

To use ASP session management on a load-balanced site, you must ensure that all requests within a user session are directed to the same Web server. One way to do this is to write a Session_OnStart procedure that uses the Response object to redirect the browser to the specific Web server on which the user's session is running. If all links in your application pages are relative, future requests for a page will be routed to the same server.

For example, a user might access an application by requesting the general URL for a site: http://www.microsoft.com. The load balancer routes the request to a specific server, for example, server3.microsoft.com. ASP creates a new user session on that server. In the Session_OnStart procedure, the browser is redirected to the specified server:

<% Response.Redirect("http://server3.microsoft.com/webapps/firstpage.asp") %>

The browser will request the specified page, and all subsequent requests will be routed to the same server.

Using Cookies

A cookie is a token that the Web server embeds in a user's Web browser to identify the user. The next time the same browser requests a page, it sends the cookie it received from the Web server. Cookies allow a set of information to be associated with a user. ASP scripts can both get and set the values of cookies by using the Cookies collection of the Response and Request objects.

Setting Cookies

To set the value of a cookie, use Response.Cookies. If the cookie does not already exist, Response.Cookies creates a new one. For example, to send a cookie name ("planet") with an associated value ("Mars") to the browser, use the following command, which must appear on your Web page before the <HTML> tag:

<% Response.Cookies("planet")="Mars" %>

If you only want a cookie to be used during the current user session, then sending the cookie to the browser is all you need to do. However, if you want to identify a user even after he or she has stopped and restarted the browser, you must force the browser to store the cookie in a file on the client computer's hard disk. To save the cookie, use the Expires attribute for Response.Cookies and set the date to some date in the future:

<%
Response.Cookies("planet") = "Mars"
Response.Cookies("planet").Expires = "January 1, 1999"
%>

A cookie can have multiple values; such a cookie is called an indexed cookie. Each cookie value is assigned a key; you can set a particular cookie key value. For example:

<% Response.Cookies("planet")("Mars")="SpaceMissions" %>

If an existing cookie has key values but Response.Cookies does not specify a key name, then the existing key values are deleted. Similarly, if an existing cookie does not have key values but Response.Cookies specifies key names and values, the existing value of the cookie is deleted and new key-value pairs are created.

Getting Cookies

To get the value of a cookie, use the Request.Cookies collection. For example, if the user HTTP request sets planet=Mars, then the following statement retrieves the value Mars:

<%= Request.Cookies("planet") %>

Similarly, to retrieve a key value from an indexed cookie, use the key name. For example, if a user sends the following HTTP request:

planet=Mars&Mars=SpaceMissions

The following script command returns the value SpaceMissions:

<%= Request.Cookies("planet")("Mars") %>

Setting Cookie Paths

Each cookie stored by ASP on the user's Web browser contains path information. When the browser requests a file stored in the same location as the path specified in the cookie, the browser automatically forwards the cookie to the server. By default, cookie paths correspond to the name of the application containing the .asp file that originally generated the cookie. For example, if an .asp file, residing in an application called UserApplication, generates a cookie, then each time a user's Web browser retrieves any file residing in that application, the browser will forward the cookie, in addition to any other cookies containing the path /UserApplication.

To specify a path for a cookie other than the default application path, you can use the ASP Response.Cookies collection's Path attribute . For example, the following script assigns the path SalesApp/Customer/Profiles/ to a cookie called Purchases:

<%
Response.Cookies("Purchases") = "12"
Response.Cookies("Purchases").Expires = "January 1, 2001"
Response.Cookies("Purchases").Path = "/SalesApp/Customer/Profiles/"
%>

Whenever the Web browser containing the Purchases cookie requests a file residing in the path /SalesApp/Customer/Profiles/ or in any of it subdirectories, the browser forwards the cookie to the server.

Many Web browsers, including Microsoft Internet Explorer version 4.0 and Netscape browsers, preserve the case of the cookie path. This means that if the path of a requested file differs from the case of the stored cookie path, the browser will not send the cookie to the server. For example, to ASP, the virtual directories /TRAVEL and /travel are the same ASP application, to a browser that preserves the case of a URL, /TRAVEL and /travel are two different applications. Make sure all URLs to .asp files have the same case to ensure that the user's browser forwards stored cookies.

If you choose, you can use the following statement to set the cookie path so that the user's Web browser will forward a cookie whenever the browser requests a file from your server, regardless of application or path:

Response.Cookies("Purchases").Path = "/"

Note, however, that forwarding cookies to the server, without distinguishing between applications, raises a potential security concern if the cookies contain sensitive information that should not be accessible outside of a specific application.

Preserving State without Cookies

Not all browsers support cookies. Even with browsers that do support cookies, some users prefer to turn off cookie support. If your application needs to be responsive to browsers that don't support cookies, you cannot use ASP session management.

If you don't use ASP session management, you must write your own mechanism to pass information from page to page in your application. There are two general ways to do this:

  • Add parameters to a URL's query string. For example:
    • http://MyServer/MyApp/start.asp?name=Jeff

    Some browsers, however, will discard any explicit parameters passed in a query string if a form is submitted with the GET method.

  • Add hidden values to a form. For example, the following HTML form contains a hidden control, which does not appear on the actual form and remains invisible in the user's Web browser. The form passes a user identification value, in addition to the information supplied by the user, by using the HTTP POST method.
    • <FORM METHOD="POST" ACTION="/scripts/inform.asp">
<INPUT TYPE="text" NAME="city" VALUE="">
<INPUT TYPE="text" NAME="country" VALUE ="">
<INPUT TYPE="hidden" NAME="userid" VALUE= <%=UserIDNum(i) %>
<INPUT TYPE="submit"  VALUE="Enter">

    This method requires all link destinations that pass user information to be coded as HTML forms.

If you are not using ASP session management, you should turn off session support for your application. When sessions are enabled, ASP sends a SessionID cookie to each browser that requests a page. To turn off session support, clear the Enable Session State check box on the Application Options property sheet in Internet Service Manager.

Sessionless ASP Pages

ASP also offers you the ability to create sessionless pages, which you can use delay the creation of sessions until a user visits an ASP page requiring session tracking.

Sessionless pages do not carry out the following:

  • Execute Session_OnStart procedures.
  • Send session ID cookies.
  • Create Session objects.
  • Access built-in session objects or session scope objects created with the <OBJECT> tag.
  • Serialize execution with other session requests.

To configure an .asp file as sessionless, use the following:

<%@ EnableSessionState=False %>

You should place this script as the first line in your .asp file, before any other scripts. The default, when this tag is omitted, enables session tracking.

Sessionless ASP pages can often improve the responsiveness of your server by eliminating potentially time consuming session activity. For example, consider the case of an ASP page containing two HTML frames: frames 1 and 2, both within one frameset. Frame 1 contains an .asp file that executes a complex script, while frame 2 contains a simple .html file. Because ASP executes session requests in sequential order, or serially, you will not be able to see the contents of frame 2 until the script in frame 1 has executed. However, if you make the .asp file for frame 1 sessionless, then ASP requests will no longer be serialized and the browser will render the contents of frame 2 before the contents of frame 1 have finished executing.

Unfortunately, the way in which multiple requests for different frames are processed ultimately depends on the configuration of the user's Web browser. Certain Web browsers may serialize requests despite the sessionless configuration of your .asp files.


Securing an ASP Application

You should not underestimate the importance of properly configured security settings. Besides exposing your ASP applications to unwanted tampering, poorly configured security settings can also keep intended users from accessing your .asp files.

Your Web server offers you a variety of methods for securing your ASP based applications from unauthorized access and tampering. After you finish reading the security information outlined in this topic, take time to carefully review your Windows NT and Web server security documentation.

NTFS Permissions

You can secure your ASP application files by applying NTFS access permissions to individual files and directories. NTFS permissions, the foundation of your Web server's security system, define the various levels of file and directory access assigned to a user or group of users. When a user with a valid Windows NT account attempts to access a restricted file, your computer checks the file's Access Control List (ACL), which defines the permissions assigned various user accounts and groups. If the user's account has sufficient permissions to open the file, the computer grants access. For example, the owner of a Web application stored on your Web server will require Change permissions to view, alter, and delete the application's .asp files. However, public users accessing the same application, should only be assigned Read permissions, which enable those users to view, not alter, the application's Web pages.

Securing the Global.asa

To fully secure an ASP application, be sure to set NTFS file permissions for the appropriate user or group on your application’s Global.asa file. If your Global.asa includes commands that return information to the browser and you do not secure Global.asa, that information will be returned to the browser, even if the application’s other files are secured.

Note Be sure to apply NTFS permissions to an application's files in a consistent way . For example, if you inadvertently apply overly restrictive NTFS permissions to an include file required by your application, users may not be able to view or run the application. To prevent such problems, develop a careful plan for assigning NTFS permissions to your applications.

Web Server Permissions

You can configure your Web server's permissions to restrict how all users view, run, and manipulate your ASP pages. Unlike NTFS permissions, which provide granular control over the way specific users access your application files and directories, Web server permissions apply to all users, and do not discriminate between different types of user accounts.

For users to run your ASP applications, you must use the following rules when setting Web server permissions:

  • Enable the Read or Script permissions for virtual directories containing .asp files.
  • Enable Read and Script permissions for virtual directories containing both .asp and other files, such as .html files, that contain scripts.
  • Enable Read and Execute permissions for virtual directories containing both .asp and other executable files, such as .exe and .dll files, which require the Execute permission to run.

Script-Mapped Files

Application script-mapping ensures that your Web server will not accidentally download the source code for an .asp file. For example, even if you set Read permissions for a directory containing a particular .asp file, your Web server will not return that file's code to the user, as long as the .asp file belongs to a script-mapped application.

Cookie Security

ASP uses SessionID cookies to track information for specific Web browsers over the course of an application visit, or session. This means that an HTTP request with a matching cookie is assumed to have come from the same Web browser. Your Web server can use SessionID cookies to configure ASP applications with user-specific session information. For example, if your application is an online music store that enables users to select and purchase compact discs, then a SessionID might be used to track each a user's selections as the user wanders throughout the application.

Can Vandals Guess the SessionID?

To prevent computer vandals from guessing the SessionID cookie and gaining access to a legitimate user's session variables, your Web server assigns a randomly generated number to each SessionID. Whenever the user's Web browser returns a SessionID cookie, the server extracts the SessionID and the assigned number. The server then checks this number against a generated number, stored exclusively on the server. If the numbers match, the user obtains access to session variables. The effectiveness of this technique lies in the length of the assigned number (64-bits), which makes it highly unlikely that a computer vandal could hijack a user's active session by guessing the SessionID.

Encrypting Sensitive SessionID Cookies

A computer vandal, able to intercept a user's sessionID cookie, could use the cookie to impersonate that user. If an ASP application contains private information, a credit card or bank account number, then a vandal with a stolen cookie could start an active session on the application and access this information. You can prevent interception of SessionID cookies by encrypting the communication link between your Web server and the user's browser.

Protecting Restricted ASP Content with Authentication

You can require that every user attempting to access your restricted ASP content have a valid Windows NT account user name and password. Each time a user attempts access restricted content, your Web server authenticates, or confirms, the user's identity to ensure that the user has a valid Windows NT account.

Your Web server supports several authentication methods including:

  • Basic authentication Prompts users to enter user names and passwords.
  • Windows NT Challenge/Response authentication Cryptographically obtains user identification information from the user's Web browser.

However, your Web server will authenticate users only if you disable anonymous access or when the Windows NT File System permissions restrict anonymous access.

Protecting the Metabase

ASP scripts that access the metabase require administrator privileges on the machine on which your Web server is running. When you execute these scripts from a remote machine, you must connect through an authenticated connection, such as a connection using the Windows NT Challenge/Response authentication method. You should create a server or directory for your administrative .asp files and set the directory security authentication method to Windows NT Challenge/Response for the server or directory. Currently, only Microsoft Internet Explorer, version 2.0 or later, supports Windows NT Challenge/Response authentication.

Securing Applications with SSL

The Secure Sockets Layer (SSL) 3.0 protocol, implemented as a Web server security feature, provides a secure virtually impervious way of establishing an encrypted communication link with users. SSL guarantees the authenticity of Web content and reliably verifies the identity of users accessing restricted Web sites.

With SSL, you can require users attempting to access your ASP application to establish an encrypted communication link with your server; preventing the interception of sensitive information exchanged between the user and the application.

Securing Included Files

If you include a file that resides in an SSL-enabled directory from an .asp file that resides in an unsecured virtual root, SSL is not applied to the included file. Thus, to ensure that SSL is applied, be sure that both the including and the included files reside in SSL-enabled directories.

Client Certificate Authentication

A highly secure way regulate access to your ASP applications is to require users to log on with a client certificate. A digital identification containing information about the identity of the user, client certificates perform the same function as conventional forms of identification, such as a passport or driver's license. Users usually obtain client certificates from a trusted, third-party organization that verifies identification information before issuing a certificate. (Typically, these organizations will require a name, address, phone number, and organization name, however, the extent of this information can vary depending the level of identification assurance required from the certificate.)

Whenever a user attempts to log on to an application requiring a certificate, the user's Web browser automatically forwards the certificate to the server. If your Web server's Secure Sockets Layer (SSL) certificate mapping features are properly configured, your server can authenticate the user before permitting access to an ASP application.

ASP Scripts for Processing Certificates

As an ASP application developer, you can write scripts to confirm the presence of a certificate and read certificate fields. For example, you can access the user name or company name fields from the certificate. Active Server Pages stores certificate information in the ClientCertificate collection of the Request object.

Before you can process client certificates with ASP, however, your Web server must be configured to either accept or require a client certificate; otherwise the ClientCertificate collection will be empty.


Creating Transactional Scripts

Frequently business applications need to the ability to run scripts and components within transactions. A transaction is a server operation that succeeds or fails as a whole, even if the operation involves many steps (for example, ordering, checking inventory, and billing). You can create ASP scripts that run within a transaction so that if any portion of the script fails, the entire transaction is aborted.

ASP transaction processing is based on Microsoft® Transaction Server (MTS), a transaction processing system for developing, deploying, and managing high performance, scalable, and robust enterprise, Internet, and intranet server applications. Transaction Server defines an application programming model for developing distributed, component-based applications. It also provides a run-time environment for deploying and managing these applications.

The functionality required to create transactional scripts is built into Internet Information Server and Personal Web Server. If you install Microsoft Transaction Server, you can also package components so they run within transactions.

About Transactions>

A transaction is an operation that succeeds or fails as a whole. Transaction processing is used to update databases reliably. When you are making many related changes to a database or updating several databases at once, you want to ensure that all of the changes are correctly executed. If any of the changes fail, you want to restore the original state of the database tables.

Without MTS, you would have to write your scripts and components to manually track the requested changes and restore data if any changes failed. With MTS, you simply declare your scripts and components to require transactions and let MTS handle the transaction coordination. Transaction processing applies only to database access; MTS cannot roll back changes to the file system or changes to other, nontransactional resources. The database your application accesses must be supported by MTS. Currently MTS supports SQL Server and any database that supports the XA protocol from the X/Open consortium. MTS will continue to expand its support for other databases.

A transaction cannot span multiple ASP pages. If a transaction requires objects from several transactional components, you should group operations that use those objects into one ASP page. For example, suppose you have a component that updates a payroll database and a component that updates employee records in a human resources database. To record new salary information for an employee, you might want to write a script that calls both components under one transaction context to update the payroll database and to update the employee's grade or level in the human resources database.

Declaring a Transactional Script

When you declare a page to be transactional, any script commands and objects used on the page are run under the same transaction context. Transaction Server handles the details of creating the transaction and determining whether the transaction succeeds (commits) or fails (aborts). To declare a page transactional, add the @TRANSACTION directive to the top of the page:

<%@ TRANSACTION = value %>

The value argument can be one of the following:

Value | Meaning
Requires_New | Starts a new transaction.
Required | Starts a new transaction.
Supported | Does not start a transaction.
Not_Supported | Does not start a transaction.

The @TRANSACTION directive must be the very first line on the page, otherwise an error is generated. You must add the directive to each page that should be run under a transaction. The current transaction ends when the script finishes processing.

Most applications only require transaction context for certain operations. For example, an airline site might use transactional scripts for ticket purchasing and seat assignments. All other scripts could be safely run without a transaction context. Because transactions should be used only for pages that need transaction processing, you cannot declare an application's Global.asa file as transactional.

If a transaction is aborted, Transaction Server rolls back any changes made to resources that support transactions. Currently, only database servers fully support transactions as this data is the most critical to enterprise applications. Transaction Server does not roll back changes to files on a hard disk, ASP session and application variables, and collections. You can, however, write scripts that restore variables and collections by writing transaction events, as described later in this topic. Your script can also explicitly commit or abort a transaction if an operation such as writing data to a file fails.

Committing or Aborting a Script

Because Transaction Server tracks transaction processing, it determines whether a transaction has completed successfully or failed. A script can explicitly declare that is aborting a transaction by calling ObjectContext.SetAbort. For example, your script might abort a transaction if it receives an error from a component, if a business rule is violated (for example, if the account balance falls below 0), or if a nontransactional operation, such as reading from or writing to a file, fails. The transaction is also aborted if the page times out before the transaction is completed.

Writing Transaction Events

A script itself cannot determine whether a transaction has succeeded or failed. However, you can write events that are called when the transaction commits or aborts. For example, suppose you have a script that credits a bank account, and you want to return different pages to the user depending on the status of the transaction. You can use the OnTransactionCommit and OnTransactionAbort events to write different responses to the user.

<%@ TRANSACTION = Required %>

<%
'Buffer output so that different pages can be displayed.
Response.Buffer = True
%>

<HTML>
<BODY>
<H1>Welcome to the online banking service</H1>

<%
Set BankAction = Server.CreateObject("MyExample.BankComponent")
BankAction.Deposit(Request("AcctNum"))
%>

<P>Thank you.  Your transaction is being processed.</P>
</BODY>
</HTML>

<%
' Display this page if the transaction succeeds.
Sub OnTransactionCommit()
  Response.Write "<HTML>"
  Response.Write "<BODY>"
  Response.Write "Thank you.  Your account has been credited."
  Response.Write "</BODY>"
  Response.Write "</HTML>"
  Response.Flush()
end sub
%>

<%
' Display this page if the transaction fails.
Sub OnTransactionAbort()
  Response.Clear()
  Response.Write "<HTML>"
  Response.Write "<BODY>"
  Response.Write "We are unable to complete your transaction."
  Response.Write "</BODY>"
  Response.Write "</HTML>"
  Response.Flush()
End sub
%>

Registering a Component in MTS Explorer

To participate in a transaction, a component must be registered in an MTS package and must be configured to require a transaction. For example, if your script processes orders by calling a component that updates an inventory database and a component that updates a payment database, you would want both components to run under a transaction context. Transaction Server ensures that if either component fails, the entire order is rolled back and neither database is updated. Some components do not require transactions; for example, the Ad Rotator component has no need of transactions.

You use MTS Explorer to register and configure a transactional component. You must set the transaction attribute to either Requires a Transaction or Requires a New Transaction. Components must be registered in an MTS package. Do not put your components in the IIS in-process package; instead, create your own package. Generally, you should put all your components in one library package. Components in library packages can be used by multiple ASP applications and are run in the ASP application process. Use MTS Explorer to create a new package and then set the package's Activation property to Library.

You can also register transactional components in a Server package, a package that always runs in a separate process on the server. You use Server packages for your transactional components if you want to use role-based security or if you want your components to be accessible from applications on remote computers.

You must have Microsoft Transaction Server installed to use MTS Explorer.

Object Scope

Generally, you should not store objects created from an MTS component in the ASP Application or Session objects. MTS objects are deactivated when the transaction is completed. Because the Session and Application objects are intended for object instances that can be used across multiple ASP pages, you should not use them to hold objects that will be released at the end of a transaction.

An ASP script is the root, or start, of a declared transaction. Any MTS object used on a transactional ASP page is considered part of the transaction. When the transaction is completed, MTS objects used on the page are deactivated, including objects stored in the Session or Application object. Subsequent attempts to call the session-scope or application-scope object from another transactional page will fail.

Queuing Transactions

Updates to a database on a remote server could delay or abort the completion of a transaction due to network delays or failures. Because all portions of a transaction must be committed, your application might be held up waiting for the commit or abort message from the remote server or might abort a transaction because the database update could not be sent.

For updates that must be completed simultaneously, it is appropriate to abort or even delay the completion of the transaction until all participants in the transaction can commit. For example, an airline ticket-ordering application should complete both the debit to a customer's bank account and the credit to the airline's bank account simultaneously. If an update is integral to a transaction but could occur later than the other updates, you might prefer not to keep the customer waiting for the completion of the update. For example, a transaction to order an airline ticket might also send a special meal request to a food services vendor or update the customer's mileage. These activities must be completed, but could be completed later.

The Microsoft Message Queue Server enables you to bundle an update or set of updates into a transactional message that is delivered to a remote server. The Message Queue Server guarantees that updates will be delivered to the remote server, even if the network is currently unavailable. Your application receives a commit message and can continue with the transaction.


Working with International Sites

One of the advantages of distributing information over the Internet or over an intranet is that you can create international Web sites that users can access from different countries. Users can request pages that have been localized into their own language, which they read in localized browser versions. When you create a Web site that contains pages in different languages, you may need to convert strings that are passed between the browser and the Web server or between an ASP script and an ActiveX component. For example, if a Japanese browser sends form or query string values in the HTTP request, the strings must be converted from the browser's Japanese character set into the character set that ASP uses to process scripts.

If all pages on the Web site are written in the default character set used by the Web server, ASP does the conversion automatically. If you author pages in different character sets, however, you need to use ASP commands that specify how the strings should be converted. For example, if your site contains some pages in one of the Japanese character sets and others in one of the Chinese character sets, you need to specify which character set ASP should use while processing strings for a particular page.

ASP also provides commands that support the cultural conventions for different locales, such as the format used for currency, time, and date. As with the string conversion commands, you only need to use the locale commands if your scripts do not use the default locale for the Web server.

Setting the Code Page for String Conversions

A code page is an internal table that the operating system uses to map symbols (letters, numerals, and punctuation characters) to a character number. Different code pages provide support for the character sets used in different countries. Code pages are referred to by number; for example, code page 932 represents the Japanese character set, and code page 950 represents one of the Chinese character sets.

Active Server Pages and the ActiveX script engines internally use Unicode, a 16-bit fixed-width character encoding standard. If you author all of your pages in the default code page of the Web server, ASP automatically converts strings. If your script was not created in the Web server's default code page, however, you need to specify the code page so that strings are correctly converted as they are passed between ASP and the script engines. In addition, you can specify the code page for strings that are passed between the browser and your script or between ActiveX components and your script.

To specify the code page for an ASP page, use the CODEPAGE directive. For example, to set the code page to Japanese, use the following directive:

<%@ CODEPAGE= 932 %>

As ASP processes the content and script on this page, it uses the code page you have specified to determine how to convert characters from your script's character set into Unicode. For example, the value that refers to the letter "a" in ANSI will be converted into the different value that refers to the letter "a" in Unicode.

Active Server Pages assumes that strings passed between the Web server and the browser, or between your script and ActiveX components, are in the same code page you have set for your script. If you need to specify a different code page, you can set the Session.CodePage property to override the CODEPAGE setting. For example, you may have authored your script in JIS but need to respond to a client that is using UTF-8 (two different character encodings for the standard Japanese character set).

Session.CodePage defaults to the value of the CODEPAGE directive; setting it overrides the current CODEPAGE setting. For example, to change the code page to Chinese, use the following command:

<% Session.CodePage = 950 %>

If you are temporarily changing the code page for a portion of your script, be sure to set Session.CodePage back to its original value. The following script shows how to temporarily change the code page:

<!-- Welcome to my home page in Japanese, code page 932 --!>
<%@ CodePage = 932 %>
...
<% Session("OriginalCodePage") = Session.CodePage %>
<!-- Look up name in Chinese, code page 950 --!>
<% Session.CodePage = 950 %>
<% Sender = ReadMailHeader("Sender") %>
<% Found = FindFriend("Sender") %>
<!-- Restore the original code page --!>
<% Session.CodePage =  Session("OriginalCodePage") %>
<% If Found == TRUE
    ReplyWithPersonalizedForm()
     else
    ReplyWithBusinessForm()
%>

Setting the Locale Identifier

A locale is a set of user preference information related to the user's language. The locale determines how dates and times are formatted, how items are alphabetically sorted, and how strings are compared. The locale identifier (LCID) is a 32-bit value that uniquely defines a locale. ASP uses the default locale of the Web server unless you specify a different locale for a particular script.

To set the locale identifier for an ASP page, use the LCID directive. For example, to set the locale to Japanese, use the following locale ID:

<%@ LCID =  1041 %>

The LCID directive tells ASP the locale in which the script was authored. If you need to change the locale for input to or output from the script, use the Session.LCID property. For example, to set the locale to Standard French, use the following command:

<% Session.LCID = 1036 %>

The Session.LCID property defaults to the LCID directive setting. Setting the value of Session.LCID in a script overrides the default setting.


Writing Cross-Platform Applications

ASP applications can be run on computers running Windows NT 4.0 or later and Windows 95 or later. In addition, a streamlined version of ASP is available on the Macintosh. Because Personal Web Server on Windows 95 and on the Macintosh are intended for personal publishing, there are some differences in the support for ASP applications. You can easily run applications developed on the personal publishing platforms on servers running Windows NT Workstation or Windows NT Server. This topic describes some of the differences between the platforms.

ASP on the Macintosh

The Macintosh version of ASP is intended for personal publishing and provides a simpler interface to ASP scripting. As a result, some of the features of ASP on the Windows platform are not available on the Macintosh. For more information, refer to the Macintosh ASP documentation.

The Macintosh version of ASP provides built-in objects that are not automatically available on the Windows platforms. The Windows platforms are shipped with components that provide these objects; however, you must declare these objects in the application's Global.asa file for your scripts to run without modification on the Windows platforms.

ASP on Windows 95

Windows 95 or later is intended as a personal publishing platform. Although running ASP applications is fully supported, Personal Web Manager does not expose the more complex administration features that a Web developer might require, such as changing script and session timeouts.

ASP on Windows NT Workstation

Windows NT Workstation is a full development platform that supports all of the scripting features of ASP. The default administration tool, Personal Web Manager, is designed for Web administrators who are not full-time server administrators. For the Web developer who wants complete control of a server site during the development and testing of ASP applications, Internet Service Manager is the appropriate administration tool. You can run the Setup program for Personal Web Server to install Internet Service Manager.