ASP
Home Up Search Trademarks how to use

For best results: this site requires that cookies be enabled for proper operation - see Legal Page for more info

Starting December 1, 2006 Techsinfo.be will no longer be available please update your links to http://techinfo.e2uhosting.net Thank you

Select Any of These

ASP

LAST UPDATED: 22 May 2006 19:18:21 +0200

This page is currently under redevelopment.  So it will be changing.  Thank you.

Translate this page      using FreeTranslation.com

A ONE-PAGE WEB SITE   A QUICK BACK LINK   ACCESSING CLIENT MACHINE INFORMATION

ACCESSING OBJECT PROPERTIES  ACCESSING REQUEST DATA

ACCESSING SQL SERVER THROUGH AN ASP PAGE   ADDING A SPELL-CHECKER

ADDING COMMENT BLOCKS   ADDING DEBUGGING STATEMENTS

ADDING NEW TEMPLATES FOR VISUAL INTERDEV   ADDING PERMANENT DEBUGGING CODE

ADDING PLAIN HTML TO THE OUTPUT     ADDING RECORDS TO TABLES WITH AUTOINCREMENT FIELDS

ADO 2.5    ALWAYS PROVIDE A CASE ELSE     ASP AND DATABASE SUPPORT

ASP CERTIFICATION TESTS    ASP CODE DOESN'T GO ACROSS THE WEB

ASP CODE DOESN'T GO ACROSS THE WEB--PART 1 OF 2

ASP CODE DOESN'T GO ACROSS THE WEB--PART 2 OF 2

ASP CODE NOT EXECUTING   ASP COMMENT BLOCKS    ASP CRASH COURSE WEB SITE NOW AVAILABLE

ASP FILE NOT PROCESSING    ASP MAGIC EIGHT BALL    ASP NOT LOADING IN NETSCAPE

ASP ON OTHER PLATFORMS    ASP PAGES CAN'T CONTROL GRAPHICAL APPLICATIONS

ASP+ NEWSGROUPS    ASP+ RESOURCE DIRECTORY    ASP-BASED CHAT SYSTEM

ASPERROR OBJECT    ATTACHING FILES TO E-MAIL    AVOID THE ADO ADDNEW AND DELETE METHODS

BROWSER-SPECIFIC CODE     BUFFERING AND DEBUG STATEMENTS    BUFFERING IN WINDOWS 2000

BUILDING A FORMAT FUNCTION--PART 1 OF 2    BUILDING A FORMAT FUNCTION--PART 2 OF 2

BUILDING A LIST AUTOMATICALLY    BUILDING A SORTING QUERY

BUILDING ARRAYS DYNAMICALLY    BUILDING MULTIPAGE FORMS    CACHING OBJECT DATA

CALLING ANOTHER PAGE    CALLING SUBROUTINES    CAN'T CLONE RECORDSET

CASE SENSITIVITY IN THE REPLACE FUNCTION--PART 1 OF 2 

CASE SENSITIVITY IN THE REPLACE FUNCTION--PART 2 OF 2 

CDO LIBRARY AVAILABLE FOR DOWNLOAD    CHANGING TIME FOR A VIRTUAL SERVER

CHANGING URL PARAMETERS    CHECKING CHECK BOXES    

CHECKING FOR EMPTY VS. CHECKING FOR NULL    CLASSES IN VBSCRIPT    CLEANING YOUR SQL DATA

CLIENT VERSUS SERVER VALIDATION    CLIENT-SIDE SCRIPTING VS. SERVER-SIDE SCRIPTING

CLOSING RECORDSETS     COM COMPONENTS AND TEXT GENERATION

COMBINING ASP, EXCEL, XML, AND XSL    COMMENT YOUR CODE    COMPARING DATE VALUES IN SQL SERVER

COMPLETELY HIDING YOUR ASP CODE    CONDITIONAL SERVER-SIDE INCLUDES

CONFIGURING PERSONALIZATION AND MEMBERSHIP SERVER

CONNECTING TO ACCESS 2000    CONNECTING TO NON-MICROSOFT DATABASES

CONVERTING BITS TO YES/NO VALUES    COOKIE LIMITS    COUNTING RECORDS IN A RECORDSET

CREATEOBJECT FAILED    CREATING A DUAL-PURPOSE PAGE    CREATING A JAVA OBJECT IN ASP

CREATING A PAGE COUNTER    CREATING A QUICK ROLLOVER     CREATING A QUICK SEARCH BOX

CREATING A REGISTRATION COOKIE   CREATING A TOP QUERY     CREATING A WRITELINE FUNCTION

CREATING FORWARD-ONLY RECORDSETS  CREATING HIDDEN INPUT FIELDS 

CREATING OBJECTS    CREATING STATELESS PAGES    CREATING WINDOWS SCRIPT COMPONENTS

DATA ACCESS CONSTANTS AVAILABLE    DATABASE FIELD DUMP    DATABASE PERFORMANCE TESTING

DATE AND TIME FUNCTIONS    DEALING WITH SINGLE QUOTES    DEALING WITH THE BACK BUTTON

DEJA.COM IS NOW GOOGLE.COM     DELETING A COOKIE    DELETING DEPENDENT RECORDS

DELETING RECORDS, REVISITED     DEPLOYING AN ASP APPLICATION    DETECTING A SECURE CONNECTION

DETECTING A SECURE PORT    DETECTING INTERNET EXPLORER        DETERMINING A DATABASE PATHNAME

DETERMINING AND CHANGING THE DEFAULT DATABASE    DETERMINING HOW MANY RECORDS ARE AFFECTED

DETERMINING IF A FIELD CAN BE NULL    DEVELOPERSITES.COM

DIFFERENT TYPES OF COOKIES    DISABLING COOKIES    DISABLING SESSION COOKIES

DISPLAYING A MESSAGE BOX   DON'T INSTALL WEB SERVER PATCH    DON'T USE ID FOR SORTING 

DON'T USE OBJECTS IN SESSION VARIABLES    DOWNLOAD A NEW ADOVBS.INC

DYNAMIC COPYRIGHT LINE    DYNAMIC SERVER-SIDE INCLUDES, REVISITED

ELIMINATE SPACE IN TABLES    ELIMINATE TOP AND LEFT MARGINS    EMBEDDING DOUBLE QUOTES

EMBEDDING NEW LINES IN EMAIL    ENCODING YOUR SCRIPT    ENCRYPTING COOKIE INFORMATION

ENCRYPTING THE QUERY STRING    ENVIRONMENT VARIABLE DUMP    ERROR WHEN CREATING COOKIES

ERRORS OPENING ACCESS DATABASES     EXPORTING DATA FROM ASP PAGES

FILESYSTEMOBJECT CONSTANTS    FILTERING A RECORDSET    FILTERING BY MULTIPLE FIELDS

FINDING A PLACE TO BUILD ASP PAGES    FINDING INFINITE LOOPS    FINDING OLE DB PROVIDERS

FINDING OUT WHERE THE USER CAME FROM    FLEXIBLE CLIENT-SIDE VALIDATION

FORM SUBMISSION LIMITS    FORMATTING PHONE NUMBERS

GENERATING STATIC HTML FROM ASP    GETSTRING METHOD    GETTING A LIST OF TABLES

GETTING BROWSER CAPABILITIES    GETTING BROWSER CAPABILITIES 2

GETTING DATA FROM TWO (OR MORE) DATABASES    GETTING INFORMATION FROM EXTERNAL WEB SITES

GETTING NEWLY CREATED RECORD ID    GETTING SECURITY INFORMATION    GETTING THE PAGE NAME

GETTING THE PREVIOUS PAGE WITH HTTP_REFERER    GLOBAL.ASA NOT REQUIRED    GREEKING TEXT

HANDLING MULTIPLE CHECK BOXES   HANDLING MULTISELECT HTML LISTS    HARDCODING PAGE NAMES

HEADER ERRORS WITH REDIRECT METHOD    HIGH TRAFFIC CRASHES WEB SITE        

HIGHLIGHTING SEARCH RESULTS    HOW TO USE SSL    HTTPS SERVER VARIABLE

IIS FAQ    ILLEGAL OPERATION ERRORS IN INTERNET EXPLORER    IMPROVING OUTPUT PERFORMANCE

IMPROVING SITE PERFORMANCE--PART 1 OF 4    IMPROVING SITE PERFORMANCE--PART 2 OF 4

IMPROVING SITE PERFORMANCE--PART 3 OF 4    IMPROVING SITE PERFORMANCE--PART 4 OF 4

INCLUDING REMOTE FILES    INDEXING ROBOTS AND YOUR SITE    

IN-PAGE LINKS AND QUERYSTRING PARAMETERS    INPUT BOXES FOR NUMBERS    INSTALLING ASP+

INSTALLING PERSONAL WEB SERVER    INTEGRATION WITH QUICKBOOKS

KNOW WHEN TO USE WHICH LANGUAGE

LEARNING XML    LIMIT GLOBAL VARIABLES    LIMITING RESULTS    LIMITING SEARCH RESULTS

LINKING TO EXTERNAL SITES    LISTING THE SYSTEM DSNS    LONG-RUNNING ASP PAGES

MACROMEDIA ULTRADEV REVIEWED    MAINTAINING STATE BETWEEN WINDOWS    

MANAGING IMAGES WITH A DATABASE    MANAGING SAVED RECORDSETS

MANUALLY CREATING A RECORDSET    MANUALLY CREATING A RECORDSET--PART 1 OF 3

MANUALLY CREATING A RECORDSET--PART 2 OF 3    MANUALLY CREATING A RECORDSET--PART 3 OF 3

MANUALLY INCLUDING A FILE    METHOD=POST VS. METHOD=GET    

MICROSOFT .NET FRAMEWORK SDK AVAILABLE    MICROSOFT ACCESS AND WEB SERVERS

MICROSOFT DATA ENGINE VS. MICROSOFT ACCESS    MICROSOFT PARTY LINE ON VBSCRIPT AND JSCRIPT

MIGRATING FROM IIS 4 TO IIS 5    MODIFYING A RECORD'S PRIMARY KEY    MODULARIZING HTML RENDERING

MORE ASP TIPS AT ASPTIPS.COM    MOVE METHODS NOT AVAILABLE    MOVEPREVIOUS NOT WORKING

MTS COMPONENTS MUST BE REGISTERED    MULTI-LINE COMMENTS    MULTI-LINE COMMENTS IN ASP 

MULTIPLE SUBMIT BUTTONS ON A FORM

NEW FEATURES AT ASP TECHNIQUES    NEW TIMER FUNCTION    NO CONTROL ARRAYS IN VBSCRIPT

ODBC AND ADO    OMIT EMPTY GLOBAL.ASA FILE    OPENING THE LOCAL SQL SERVER

OPTION EXPLICIT IN ASP+    OPTIONAL FEATURE NOT IMPLEMENTED    OPTIONS FOR ORDERED LISTS

OWNERSHIP OF CODE

PAGE SIZE ISSUES    PAGING THROUGH LARGE RECORDSETS    PASSING VARIABLES BETWEEN PAGES

PERFORMANCE IMPROVEMENTS IN IIS 5.0    PERMANENT VS. TEMPORARY COOKIES    

PERMISSION DENIED FOR E-MAIL    PERSISTING A RECORDSET    PERSONAL WEB SERVER AND WINDOWS ME

PERSONAL WEB SERVER WORKSHOP    PREVENTING A PAGE FROM CACHING    

PRINTING VALUES WITHOUT THE RESPONSE.WRITE STATEMENT    PROBLEMS WITH ACCESS DATABASES

PROBLEMS WITH CDONTS.NEWMAIL    PROTECTING YOURSELF FROM SCRIPTING ATTACKS

PUTTING IIS AND WINDOWS 2000 ON A LAPTOP    

READ PROPERTIES SPARINGLY    READING USER'S EMAIL ADDRESS    READY OR NOT, HERE COMES XML

REBOOTING THE WEB SERVER    RECORDCOUNT = -1    REGISTER YOUR DLLS    REGISTERING A DOMAIN

REGISTERING DLLS     RELEASING OBJECTS    REMEMBER TO SET COMMANDTYPE 

REMEMBERING A USER'S INPUT    REMEMBERING A USER'S INPUT part 2    REMOTE ADMINISTRATION    

 REMOTE SERVER-SIDE INCLUDES    REMOTELY RESTARTING THE SERVER

REMOVING YOUR SITE'S COOKIES    REQUEST OBJECT COLLECTIONS ARE OPTIONAL

RESERVED WORDS AS VARIABLES    RETRIEVING RECORDSETS    

RETRIEVING XML DATA INTO ASP    RUNNING ASP SCRIPTS

SAFELY SHOWING VALUES IN FORM FIELDS    SAVING A RECORDSET    SAVING SEARCHES

SCHEDULING A PAGE    SCRIPT TIMEOUTS    SCRIPTLESS ASP FILES    

SEARCHING LONG TEXT FIELDS IN SQL SERVER    SEARCHING TEXT FILES    SENDING DATA TO EXCEL

SENDING DATA TO MICROSOFT WORD    SENDING E-MAIL FROM ASP    SENDING EMAIL WITHOUT A COMPONENT

SENDING PLAIN TEXT    SERVER.CREATEOBJECT FAILED    SERVER.EXECUTE WORKS LOCALLY

SERVER.TRANSFER VS. RESPONSE.REDIRECT    SERVER-SIDE INCLUDES FOR REMOTE FILES

SESSION VARIABLES AND LOAD BALANCING    SHOWING GRAPHS AND CHARTS ON A WEB PAGE

SHOWING HTML EFFICIENTLY    SHOWING VALUES IN FORM FIELDS    SIMPLE EMAIL VALIDATION

SINGLE QUOTES AND SQL    SITE SERVER'S DIRECTMAIL FUNCTIONALITY    SITEEXPERTS.COM

SPECIFYING NETWORK LIBRARY FOR SQL SERVER    SQL SERVER FOR STRING PROCESSING

STACK RECORDSET RETURNS    STANDALONE ASP DEVELOPMENT    

STATE PRESERVATION AND THE SESSION OBJECT    STORING PICTURES IN A DATABASE

STRUCTURING YOUR INCLUDE FILES    SUBSCRIBE TO ASPWIRE    SYSTEM LIBRARY LOCATIONS

TESTING ASP APPLICATIONS    TEXT BOX DATA TRUNCATED    THE FILE ACCESS COMPONENT

TIMER FUNCTION FIXES    TIMING OUT A LOGIN    TIMING THE EXECUTION OF SCRIPTS

TRACKING CLICKTHROUGHS TO AN EXTERNAL SITE    TRACKING IP ADDRESSES    TUTORIAL ON COOKIES

UPDATING A DATE/TIME FIELD IN SQL SERVER    UPDATING AN ACCESS DATABASE

UPDATING COMPONENTS AND MICROSOFT TRANSACTION SERVER    USE CONSTANTS FOR FILENAMES

USE SERVER.TRANSFER INSTEAD OF RESPONSE.REDIRECT    USING ACCESS DATABASES WITH ASP

USING ASP WITH ODBC DATABASES    USING ASSIGNMENT STATEMENTS    USING CLASSES IN VBSCRIPT 5.0

USING MOVE METHODS WITH RECORDSETS    USING MTS COMPONENTS WITH ASP    USING OPTION EXPLICIT

USING PARAMETERIZED STORED PROCEDURES    USING PERLSCRIPT WITH ASP    USING SERVER.EXECUTE

USING SERVER.HTMLENCODE    USING SESSION VARIABLES    USING SESSION VARIABLES FOR SECURITY

USING SQL SERVER FOR DATE PROCESSING    USING SQL SERVER FOR STRING PROCESSING

USING STYLE SHEETS AND SQL FOR OUTPUT    USING THE ADO FIELD ATTRIBUTES PROPERTY

USING THE BILL OF MATERIALS STRUCTURE    USING THE EVAL FUNCTION    

USING THE JET 4.0 PROVIDER WITH ACCESS 97    USING THE LIKE KEYWORD    USING THE METADATA TAG 

USING THE RECORDSET SORT PROPERTY    USING VARIANTS IN COM COMPONENTS    

VALIDATING ADDRESSES    VALIDATING AND CLEANING TEXT    VALIDATING DATA    

VALIDATING EMAIL ADDRESSES, REVISITED    VBSCRIPT IN MSGBOX TITLE    VIEWING A LIST BOX'S DATA

VIEWING ASP PAGES IN INTERNET EXPLORER    VISIT ACTIVE SERVER CORNER    

VISUAL BASIC DIRECTORY AT ABOUT.COM    VISUAL SOURCESAFE AND ASP    

VISUAL STUDIO SERVICE PACK 4 AVAILABLE

WHAT IS ASP ERROR 0115?    WHAT'S WRONG WITH RENDER BLOCKS    WHEN A SESSION EXPIRES

WHERE TO PUT COOKIE CODE    WHERE TO VALIDATE DATA    WHICH ORACLE DRIVER TO USE

WORKING WITH MULTIPLE CHECK BOXES    WORKING WITH MULTIPLE FORMS    

WORKING WITH MULTIPLE SUBMIT BUTTONS    WORKING WITH SQL SERVER CURRENCY FIELDS

WORKING WITH THE BACK BUTTON    WRITECOMMENT FUNCTION    WRITING A WEB PAGE COUNTER

WRITING AN XML FILE

MANAGING IMAGES WITH A DATABASE

For those of you interested in storing images in a database, I have two words for you: Don't bother. While you can do it, it's much easier to do the following.

First, create a field in your table to store a filename. Then, store the image on disk somewhere with that filename. Finally, link to the image from your Web application or your client/server application.

In my experience, it's much easier to work with images in this fashion unless you have some high-performance systems specifically designed for working with large batches of images. For more users, storing the files on a shared disk makes them easier to get to for both Web and client/server applications.

ADDING PLAIN HTML TO THE OUTPUT

If you need to include plain, constant HTML in your ASP page's output, don't mess with lots of Response.Write statements to generate it. Instead, do something like this:

' ASP code
%>
<UL>
<LI>List 1
<LI>List 2
</UL>
<%
' more ASP code

This makes your code easier to read and is a lot easier than crafting lots of Response.Write statements.

USING ASSIGNMENT STATEMENTS

In ASP, you can cause a variable or expression to be printed using the <% = syntax. However, you can't make the statement longer than one line. If you are using this syntax and need to make your assignment longer than a single line, use a Response.Write to do it instead, or break the assignment into multiple sections. Since ASP only inserts
line breaks where you put in HTML-based line breaks (P or BR tags), you don't have to worry about a value printing on more than one line.

COMMENT YOUR CODE

One of the biggest faults of ASP programmers is that they don't comment their code. Comments make it easier for both you and other programmers to understand what you were thinking when you wrote the code. You have two main ways of commenting your code. The first is an HTML comment that should not be placed within the ASP delimiters:

<!-- this is an HTML comment -->

The other type of comment goes within the ASP delimiter tags and is marked with a single quote, as shown here:

<%
' This comment goes within ASP code
%>

These comments aren't sent to the user's browser, whereas the HTML comments are, so be careful what content you're putting in your comments. Storing your database passwords and IP addresses in HTML-based comments is not normally a good idea.

RETRIEVING RECORDSETS

If you need a read-only copy of data from a database to populate some sort of list or table, the best type of recordset to use is a forward-only, read-only recordset. The code to do this is

Dim dcnDB ' As ADODB.Connection
Dim rsData ' As ADODB.Recordset
Set dcnDB = Server.CreateObject("ADODB.Connection")
dcnDB.Open "some connection string"
Set rsData = dcnDB.Execute("SELECT * FROM LookupTable")

The default recordset is a read-only, forward-only recordset using this method.

INSTALLING PERSONAL WEB SERVER

A reader alerted me to the fact that Personal Web Server is also available on the Windows 98 CD-ROM. This version includes the ASP engine, Transaction Server, and Message Queues. PWS is installed automatically with FrontPage 98. You have to install the ASP engine manually, but the instructions for doing this are included in the 60-Minute Intranet Kit. Apparently, installing from the NT Option Pack has caused problems for people, as evidenced by the number of
questions and issues raised in the Usenet groups relevant to this product.

PROBLEMS WITH ACCESS DATABASES

Here's a quick tip if you're using an Access database (or other file-based database) with Active Server Pages. You have to make sure that the directory in which the database lives is marked as writeable for the user ID used by the IIS process. Otherwise, the database won't operate properly from your ASP applications.

MULTIPLE SUBMIT BUTTONS ON A FORM

If you have a form with multiple SUBMIT buttons on it, you can determine which button was clicked by looking at the button's value in the Request.Form data collection. If the button has a value, it was the one pressed. For instance:

<form action="submit.asp" method="post">
<input type=submit name=cmdButtonA value="A">
<input type=submit name=cmdButtonB value="B">
</form>

Your ASP code would check Request.Form("cmdButtonA") against an empty string. If the value in cmdButtonA is not an empty string, Button A was pressed.

USING OPTION EXPLICIT

If you don't regularly declare your variables, you can run into problems with typos in variable names. VBScript by default automatically creates variables as it sees the names. However, if you put Option Explicit as the very first line in your file, all variables will have to be declared in the page. Just add it to the top of the file like this:

<% Option Explicit %>

Make sure you put it before any other script code or you'll get an error, since this line has to be the very first line in the file.

PRINTING VALUES WITHOUT THE RESPONSE.WRITE STATEMENT

If you are embedding HTML in your ASP page, you can print variables and expressions without having to use the esponse.Write statement. Here's an example:

<UL>
<LI><% = rsData("UserID") %>

This will print out the value of the UserID field of the rsData recordset immediately following the LI tag. The only restriction is that you can't stretch the delimiters over more than one line.

ASP CODE DOESN'T GO ACROSS THE WEB

I got a question the other day about how to protect your source code so users can't see it. The person asking wanted to make sure that the code he created in his ASP page wouldn't be visible on the Web. The fact is that ASP code (anything between the delimiter tags) is evaluated (and basically removed) from the ASP page before it gets sent to the user's browser. All the user gets is the HTML that's left or that you created with your ASP code.

WHAT IS ASP ERROR 0115?

Have you ever developed an ASP page and gotten an ASP Error 0115? After you get it, no matter what you do, you keep getting the same error. The reason is that 0115 means a component used by ASP has crashed, and ASP can't get anymore information from the component to help diagnose the problem. Often, the solution involves stopping and starting the IIS service. For more information on this problem, visit this URL:

http://207.141.47.107/aspfaq/0115.asp

SENDING E-MAIL FROM ASP

One of the most common questions I get is how to send e-mail from an ASP page. Using the Collaboration Data Objects (CDO), it's quite easy. The object you need is the CDONTS.NewMail object, and it can be used like so:

Dim objMail ' As CDONTS.NewMail
Set objMail = Server.CreateObject("CDONTS.NewMail")
objMail.To = "destination@host.com"
objMail.From = "sender@host.com"
objMail.Subject = "Subject goes here"
objMail.Body = "The message goes here."
objMail.Send
Set objMail = Nothing

There are several other properties and methods with this object. You can refer to MSDN for a complete list.

ATTACHING FILES TO E-MAIL

In a previous tip, you learned how to send e-mail from ASP using the Collaboration Data Objects. Besides just sending plain text, you can attach files to messages. The AttachFile method allows you to add a file to an outgoing e-mail message, as shown here:

Dim objMail ' As CDONTS.NewMail
Set objMail = Server.CreateObject("CDONTS.NewMail")
objMail.To = "destination@host.com"
objMail.From = "sender@host.com"
objMail.Subject = "Subject goes here"
objMail.Body = "The message goes here."

objMail.AttachFile "C:\Autoexec.bat", "Autoexec.bat"
objMail.Send
Set objMail = Nothing

The first parameter is the pathname to the file. The second parameter is the name that appears with the attachment in the person's e-mail. This is especially helpful if you have a long pathname or don't want to show the user the original filename.

SESSION VARIABLES AND LOAD BALANCING

A number of readers have written about the positives and negatives of using Session variables. In an article by Bart  Gerardi, the implications of Session variables are discussed when it comes to running your application in a  load-balanced environment. Check out the article at

http://www.asptoday.com/articles/20000118.htm

THE FILE ACCESS COMPONENT

A number of readers have asked me recently about the "File Access Component" of ASP. This is a bit of a misnomer and is 
not a new component of any sort. The File Access Component of ASP refers to the FileSystemObject and the related 
objects, such as File, Folder, and so on. The MSDN Library lists it as a separate component but provides a link to the 
FileSystemObject section.

USING PERLSCRIPT WITH ASP

A reader asked why we hadn't mentioned PerlScript as a language to use with ASP. Any supported scripting language on 
Windows NT can be used to write ASP code, which includes PerlScript and other languages, like Python and REXX. Feel free  to use whatever language you like . . . it's just that most documentation you'll see from Microsoft will use VBScript 
for any code examples, so you'll have to figure out how to use the objects on your own if you don't use VBScript.

USING VARIANTS IN COM COMPONENTS

If you're building COM components for your Web applications, remember that VBScript knows only one data type: Variant. This has two implications for COM components: The first implication involves parameters you might have to supply to a function or subroutine. For example, if your COM component is set to accept a Long, you'll have to use the CLng function on the input value before passing it. This is fine, but an easier way to handle this is to accept a Variant and perform any conversions after the value is inside the COM component. This has the added benefit of keeping all the conversion code in one place. Also, remember to do any necessary validation on the input.

The other implication involves return values from functions. For instance, while you might want to return an ADODB.Recordset object to your code, you should use a return type of Variant. You'll still be able to return the object, and VBScript will know how to handle the object, since you're using the Set statement to store the result in a Variant variable.

WHICH ORACLE DRIVER TO USE

In a previous tip, we talked about the Oracle driver that had been created by Microsoft when ADO was first released. At the time, it had better performance than any driver that Oracle had created. However, this situation has since changed. According to several readers, the Oracle OLE DB provider has improved dramatically and is now the recommended driver for accessing Oracle databases through OLE DB/ADO. Users estimate a 30 percent performance improvement over the Microsoft Oracle driver.

A ONE-PAGE WEB SITE

One of the goals in writing an ASP application is to minimize the number of places you have to work with code. There are lots of mechanisms for doing this, such as server-side includes, which allow you to include the contents of a common file into another.

However, in some cases you can minimize the total number of ASP files in your site by consolidating your code into one place. On the new ASP Techniques site, for instance, I have one file that is intelligent enough to show all the content on the site. Here's the code from the Sub Main routine that runs first on the page. It's just a Select/Case statement that checks the action codes and then calls the right routine. Each routine gets the appropriate key values to show the content, as well as a reference to an MTS component managing database access.


Sub Main
Dim strAction ' As String
Dim lngSectionID ' As Long
Dim lngPageID ' As Long
Dim lngCategoryID ' As Long
Dim lngContentID ' As Long
Dim strCommonID ' As String
Dim objDB ' As NCSBackOffice.Database

strAction = Request(ACTION)
Set objDB = Server.CreateObject("NCSBackOffice.Database")
Select Case strAction
Case ACTION_RETR_COMMON
strCommonID = Request("cID")
RetrieveCommonContent objDB, strCommonID

Case ACTION_RETR_SECT
lngSectionID = Request("sID")
RetrieveSection objDB, lngSectionID

Case ACTION_RETR_CAT
lngCategoryID = Request("cID")
If Request("pID") = "" Then
lngPageID = 1
Else
lngPageID = Request("pID")
End If
RetrieveCategory objDB, lngCategoryID, lngPageID

Case ACTION_RETR_CONTENT
lngSectionID = Request("sID")
lngContentID = Request("cID")
RetrieveContent objDB, lngSectionID, lngContentID
End Select
Set objDB = Nothing
End Sub
Doing something like this is all a matter of organization. It's not hard... it just takes some planning to make it work. If you're interested in this sort of development, watch the ASP Techniques site for some upcoming articles about this topic.

ACCESSING REQUEST DATA

When retrieving data from the Request object, you can access the data using one of two different methods: either directly through the Request object or indirectly through one of the collections of the Request object. While either method works fine, if you're looking to gain a bit more speed, directly select the precise collection so the system doesn't have to search all the collections for the data you want.

In addition, accessing data from the Request object is more time consuming than getting data from a locally defined variable. If you need to retrieve data more than once, create a temporary variable for the field, copy the data to it, and then use that variable whenever you need the data.

ADDING A SPELL-CHECKER

Ever wanted to provide a spell-checking feature to your Web forms? In a recent article at ASP Today, you can learn how to do this with a bit of database coding and some font formatting. Best of all, this solution doesn't require any downloaded components or expensive third-party tools.

http://www.asptoday.com/articles/20000406.htm

ADDING COMMENT BLOCKS

To remind myself what I've done to an ASP file, I will add a comment block to the top of each file (after Option Explicit, of course). This comment block usually contains the following:

Name of the file
Basic description of what the file does
Date created
Modification log containing dates, initials, and descriptions of what has been done to the file

This information helps me keep track of changes to the file, and it's especially helpful for use with a source code control program like SourceSafe or PVCS.

ADO 2.5

ADO 2.5 is included with Windows 2000, and it is also available as a separate download from the Microsoft Data Access site:

http://www.microsoft.com/data

If you go into the Program Files\Common Files\System\ADO directory, you'll find a bunch of files, some of which have version numbers in the filenames. However, there aren't any with the version number 2.5 in their names. That's because ADO 2.5 is stored in MSADO15.DLL. If you bring up the properties for this library (or any other DLL file), you'll be able to see the version number stored in the library file itself.

ASP ON OTHER PLATFORMS

If you're looking to run ASP on platforms such as Linux, the best approach (for now) is to use a product called ChiliSoft. It can handle ASP code, just like IIS, as well as custom components written in a variety of languages. It currently has broad server support and is the market leader for this technology. Visit the ChiliSoft Web site at

http://www.chilisoft.com

ASP-BASED CHAT SYSTEM

Brian Gillham has released an ASP-based chat system that you can integrate into your Web site. You can download the code, for free, from this URL:

http://www.aspfree.com/authors/briang/chat.asp

BUFFERING IN WINDOWS 2000

With the change from IIS 4.0 to IIS 5.0, there also has been a change in the way buffering is implemented. (Buffering refers to whether content from the ASP page is sent before or after the page is complete.) Under IIS 4.0, buffering is turned off by default, but in IIS 5.0, buffering is turned on. Keep in mind that if you're debugging your page and print values before you get an error, those values won't show up if the page is being buffered. To turn buffering on or off on a per-page basis, you can use this code:

Response.Buffer = True (or False)

To change the buffering status on your Web server, first use the Internet Service Manager to bring up the Properties window for your Web site. Then, select the Home Directory tab and click the Configuration button near the bottom of the window. In the resulting window, select the App Options tab and deselect (or select) the Enable Buffering checkbox. Click OK to exit and save your changes.

CHANGING TIME FOR A VIRTUAL SERVER

A reader who has his ASP site hosted at a virtual server farm asked me whether it's possible to change the system date/time for just that site. Since ASP uses the NT system time just like everyone else, the basic answer is no. However, you can easily create your own "time" and "date" functions that add or subtract time from the current system time. If you're creating a site for the UK and it's hosted in the US, you can simply add the appropriate number of hours to the US system time, and voila, you've got the UK's time.

CHANGING URL PARAMETERS

One of the disadvantages of using command-line parameters to link to an ASP file is that the user can simply change those parameters. Depending on the application and use for those numbers, this could be a security risk. If you don't want the user changing them, you need to keep the parameters out of the Web page. Even if you insert the data as hidden input fields, the user could potentially still change the file and resubmit it from his or her server. If you need to keep confidential data, leave it on the server and send a reference to that set of data instead. That way, the user won't know what he or she is changing.

CHECKING FOR EMPTY VS. CHECKING FOR NULL

Depending on the database you're using, checking a field value may involve checking it against an empty string (two double quote characters together) or against Null using the IsNull function. For numeric values, you almost always need to check them against Null, and not an empty string or zero. An easy way to test if a value is Null is to just print the value of the IsNull function in the page (or in a comment). That way, you can tell very quickly what's going on in your application.

CLEANING YOUR SQL DATA

One of the big problems people have when they're writing SQL within asP is dealing with data supplied by users. For example, you may have some code that looks like this:

Dim strSQL
strSQL = "SELECT * FROM Customers WHERE CompanyName = '" _
& Request.Form("Keywords") & "'"

This code will return all the customers where the CompanyName field is equal to whatever the person put in the Keywords field on a form. The problem comes, however, when you have a name with a single quote in it, such as the name O'Reilly. The single quote character breaks the SQL statement.

The easiest solution is to "clean" the input data before putting it into the SQL statement. Here's a quick function you can use to do just that. (Note that the SQ constant holds a single quote.)

Const SQ = "'"
Function Clean(strData)
Clean = Replace(strData, SQ, SQ & SQ)
End Function

With the Clean function in place, the original chunk of code looks like this:

Dim strSQL
strSQL = "SELECT * FROM Customers WHERE CompanyName = '" _
& Clean(Request.Form("Keywords")) & "'"

COMPARING DATE VALUES IN SQL SERVER

When comparing dates within SQL Server, you may get unexpected results if you don't remember that every date value has both date and time components in it. For instance,

6-19-2000

is not the same as

6-19-2000 7:00 PM

Because any date without a time is given a time of 00:00:00. If you do need to compare the dates, you can use any number of functions to compare month, day, and year. You can also convert both dates to text using the CONVERT function and then compare just the date portion.

COMPLETELY HIDING YOUR ASP CODE

A reader asked if there was any way to completely hide the ASP source code, even from the IIS administrator. No, I didn't ask WHY he wanted to do this, but here are a few basic facts:

* ASP source code is in a text format.
* The IIS administrator typically is the machine administrator, which means he/she can see any file on the machine.
* In order for the files to be viewed by Web visitors, they have to be readable by the Web user ID, which means they are readable by everyone.

If you don't want anyone looking at your source code, you'll have to put all the source code (or as much as possible) within a compiled component developed in VB or some other language. I do this for performance reasons, by the way, and it also doubles as a security precaution.

CONFIGURING PERSONALIZATION AND MEMBERSHIP SERVER

In an article at Microsoft's Web site, you can learn how to configure the Personalization and Membership components of Microsoft Site Server. The article is a bit aged, but the information is still correct for Site Server 3.0.

http://msdn.microsoft.com/workshop/server/nextgen/perstutor.asp

CONNECTING TO ACCESS 2000

This question keeps coming up, so I'll answer it again: To connect to an Access 2000 database, you need to use the Jet 4.0 provider with ADO/OLE DB, like so:

Dim dcnDB ' As ADODB.Connection
Set dcnDB = Server.CreateObject("ADODB.Connection")
dcnDB.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=D:\Mydatabase.mdb;"
dcnDB.Open

I've seen some users using syntax involving DBQ and curly braces, which seems to work OK. However, MSDN uses this method and syntax for examples, so that's what I stick with.

CREATING A DUAL-PURPOSE PAGE

On this site it shows another page or two to maintain the links and categories. Without creating  two sites, it  merges the administration and the viewer into a single application. At the bottom of the toolbar, there's a link to log into the page. Once I've logged into the system, I get a number of additional options on each page:

* A link to modify the existing link
* A link to delete the link
* Each category shows a link to allow me to enter a new link.
* At the top and bottom of each category page, there's a link to add new categories.

Of course, for operations I need to do infrequently, I can always go directly to the underlying database. The main idea behind this option is to consolidate all the shared code (showing a form, showing a link, etc.) in one place.

Check it out for yourself at

http://eric.northcomp.com

CREATING A JAVA OBJECT IN ASP

ASP is one of those languages that plays well with others. If you have a Java class that you want to use in ASP, you have two options, depending on what you want to do with the class. You can use Server.CreateObject to create the instance; however, the class must be registered as a COM component on the server. This can be done using the JavaReg program.

The second option is to use the GetObject statement, in which you specify the full name of the Java class, in the form java:classname. Here's an example:

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

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

Objects created by calling GetObject instead of Server.CreateObject can also access the ASP built-in objects and participate in a transaction. To use Java class names (also known as monikers), you must be using version 2.0, or later, of the Microsoft virtual machine.

CREATING A RECORDSET MANUALLY, REVISITED

One of the features of the ADO recordset is that you can create it manually. Instead of creating a recordset by way of a database, you can create a recordset, add fields of various types to it, and then add data to it. You can then manipulate it just like a database-created recordset, save it to disk, or pass it back from a component for use in an application.

After you create a recordset object, you can use the Add method of the Fields collection to create new fields. When you create these fields, you can specify the data type, the field length, and so on. Once you've added the fields, you can use the Open method to open the recordset for modification. You then use the AddNew method to create a new record, followed by the Update method to commit the record to the recordset. Refer to the ADO Fields collection for more information about this feature.

Alan Silver mentioned another use for this feature. He was retrieving filenames from disk and needed to sort them. Instead of writing his own sort routine, he created an ADO recordset, loaded the filenames (along with the other data), and used the Sort property to automatically sort the data. This is far less effort than any other sort routine I've used in the past. 

DATE AND TIME FUNCTIONS

A user asked how to use the server date/time to control access to files. The thing to remember is that any date/time functions--such as Date, Time, and Now--work based on the server's date and time, not the client computer's date and time. This, of course, assumes we're talking about server-side scripting. This is especially important when dealing with international sites and users. If you are showing a date and time, make sure you know to whom you're showing it.

DEALING WITH THE BACK BUTTON

Several people have asked me how to stop a user from clicking the browser's Back button. Typically, this causes problems for submitting form data, and it would be nice if we could prevent the user from clicking the Back button. Unfortunately, there's no completely reliable way to do this. Instead, think about designing your application to allow the user to press the Back button, just like a wizard might allow. It will involve more coding but will provide a better experience for your users.

DETECTING A SECURE PORT

If you're running a secure Web site with IIS, you can easily verify that the user is viewing a page through a secure port. Just check the HTTP variable called SERVER_PORT to determine how the user is looking at the page. Here's a snippet of code that checks the port and redirects the user to the secure site if he/she isn't using port 443 to access the site:

If Request("SERVER_PORT") <> 443 Then
Response.Redirect SECURESITE & "adm_login.asp"
Exit Sub
End If

DETERMINING HOW MANY RECORDS ARE AFFECTED

Using the ADO Connection object, you can use the Execute method to run queries. However, it's often helpful to know how many new records were created, updated, or deleted. If you pass a variable into the Execute method as the second parameter, ADO will fill that variable with the number of records that were touched. Here's an example:

Dim cnDB ' As ADODB.Connection
Dim lngRecords ' As Long
cnDB.ConnectionString = "some connection string"
cnDB.Open
cnDB.Execute "UPDATE Products SET UnitPrice = UnitPrice * 1.05", lngRecords

In this case, the variable lngRecords will hold the number of records that were updated.

ELIMINATE SPACE IN TABLES

Ever have an HTML table that doesn't quite line up in Netscape? It could be because of extra blank lines in the HTML code. While it's not supposed to make a difference to HTML, it does seem to matter to Netscape. To eliminate the chance of getting some stray white space, construct your tables like this:


<table>
<tr>
<td><!--
--><a href="test.asp"><!--
--><img src="test.gif"><!--
</a></td>
</tr>
</table>
The goal is to make everything within a TD tag a continuous line of text with no white space in the file. Using the comments to break the lines accomplishes this goal.

ELIMINATE TOP AND LEFT MARGINS

One feature available in Internet Explorer that isn't currently available (as of 4.71) in Netscape Navigator is the ability to change the margins of your HTML page. By setting the LEFTMARGIN and TOPMARGIN properties of the BODY tag, you can change how much space is displayed on the top and left of the page. The stripe is a background image, but you'll see that the text is all forced to the left edge of the page.  By setting the leftmargin and topmargin properties of the BODY tag, you can change how much space is displayed on the top and left of the page. In fact, you can eliminate these margins by setting the following parameters:

<body leftmargin=0 topmargin=0>

If you're using Netscape, you have to use different parameters in order for this to work. In Netscape, you can create this tag for the same effect:

<body marginheight=0 marginwidth=0>

If you're writing for both browsers, you can use this version of the tag as well:

<body leftmargin=0 topmargin=0 marginheight=0 marginwidth=0>

Internet Explorer 5.0 users can visit the following site to see this in action:

http://www.northcomp.com/

EMBEDDING DOUBLE QUOTES

One thing you have to do often when writing ASP is generate HTML links. This may involve embedding double quote characters in your printed output, like this:

Response.Write "<a href=""contents.asp?id=253"">Click here</a>"

While the double quotes in the link are not required, they are recommended. However, this code gets even more cumbersome if you embed a variable value for the ASP filename, as in this example that uses the SCRIPT_NAME server variable:

Response.Write _ "<a href=""" & Request("SCRIPT_NAME") & "?id=253"">Click here</a>"

To help ease this situation, I define a constant for the double quote character, called DQ, like so:

Const DQ = """"

Yes, there are four double quote characters here--the first and last delimit the string, and the inner two represent a double quote character that I want to print. Now, the previous code can be changed to

Response.Write _ "<a href=" & DQ & Request("SCRIPT_NAME") & "?id=253" _
& DQ & ">Click here</a>"

For many users, this code is easier to understand (and to write) than the three double quote characters in a row.

ENCODING YOUR SCRIPT

Users have asked me if there's a way to secure the script in a Web page. The short answer is: Yes, using the new Microsoft Script Encoder. You can download this tool (for free) from the Microsoft Scripting site:

http://msdn.microsoft.com/scripting

FILTERING A RECORDSET

If you have a recordset already created and want to filter it by some criteria, you can use the Filter property of the recordset to do it. Just change the recordset's Filter property to a WHERE clause and then set the recordset object to another recordset variable, like this:


Dim objRS, objFilter ' As ADODB.Recordset
Dim dcnDB ' As ADODB.Connection
Set dcnDB = Server.CreateObject("ADODB.Connection")
dcnDB.Open "Some connection string"
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open "SELECT * FROM tblOrders", dcnDB, adOpenStatic

objRS.Filter = "CustomerName Like %Smith%"
Set objFilter = objRS
Depending on how big the recordset is, you may want to simply do another query from the database. It will probably run faster, especially if you create a stored procedure to do the work for you. Also, make sure you have indexes on the fields that you're using in your filters.

FINDING OLE DB PROVIDERS

When you're using ADO, you have to use an OLE DB provider to access the database. If you're using a database that doesn't have an OLE DB provider, you can get one from several companies. Microsoft maintains a site with all of the third-party OLE DB providers available. Here's the URL:

OLE DB Providers List

FLEXIBLE CLIENT-SIDE VALIDATION

The ASPToday site has a good article on creating flexible, client-side, JavaScript-based validation for your Web pages. Here's the URL:

http://www.asptoday.com/articles/20000328.htm

This technique provides a good alternative to roundtrips to the server, if you are allowed to use client-side scripting in your application.

GETTING INFORMATION FROM EXTERNAL WEB SITES

Ever want to include information like stock quotes or headlines on your Web site? In this article at the FourGuysFromRolla Web site, you can see how to use the Internet Transfer control (included with Visual Basic) to do just that. Here's the URL for the article:

http://www.4guysfromrolla.com/webtech/040600-1.shtml

IMPROVING OUTPUT PERFORMANCE

To increase the performance of your Web page output, you can use output buffering. Output buffering stores all of the output while the page is being built. However, users won't see any output until the page is complete. In long-running pages, this could cause users to cancel the connection. To turn on output buffering, use this statement:

Response.Buffer = True

To cause the buffer to be sent to the user, you can call the Response.Flush method. To erase the buffer, call Response.Clear.

One of the nice things about buffering is that you can use Response.Redirect any time after you've put content in the buffer and before you send it to the user. This makes it a bit easier to code your application, but keep in mind that the user won't see any content until you've finished building the page.

Another important thing to remember is that in IIS 4.0, buffering is turned off by default. In IIS 5.0 running on Windows 2000, buffering is turned ON by default. If you've relied on using unbuffered pages, you'll need to turn off buffering at the beginning of your page.

IMPROVING SITE PERFORMANCE--PART 1 OF 4

There are some simple things you can do to improve your Web site's performance--depending, of course, on the structure of your site. For the purposes of this series of tips, let's assume you're using a database to get data and show it on the output page.

The first thing you can do to improve performance is to use predefined queries or stored procedures (depending on your database). With most databases, this feature allows the database to skip the work involved in optimizing the query. This alone will often speed up operations significantly, depending on the types of queries you're doing.

IMPROVING SITE PERFORMANCE--PART 2 OF 4

There are some simple things you can do to improve your Web site's performance--depending, of course, on the structure of your site. For the purposes of this series of tips, let's assume you're using a database to get data and show it on the output page.

One such way to improve performance is to retrieve only the fields you need from the database. There's always a temptation to simply say SELECT * FROM allmytables, when in fact you need only a field or two. Depending on the size of the table, this tip can vary in its effectiveness.

IMPROVING SITE PERFORMANCE--PART 3 OF 4

There are some simple things you can do to improve your Web site's performance--depending, of course, on the structure of your site. For the purposes of this series of tips, let's assume you're using a database to get data and show it on the output page.

If you have access to Microsoft Transaction Server (MTS) and the ability to create COM DLLs, you can gain quite a bit of performance by creating an MTS object that handles your database activity. This has the benefit of holding the connection open until a timeout period expires. Since making the connection is the most "expensive" part of getting data, you just chopped your request time down significantly.

IMPROVING SITE PERFORMANCE--PART 4 OF 4

There are some simple things you can do to improve your Web site's performance--depending, of course, on the structure of your site. For the purposes of this series of tips, let's assume you're using a database to get data and show it on the output page.

If you're doing a lot of database recordset manipulation in ASP, this is best handled within a COM DLL, since the code is all compiled. I have part of my ad system that's currently in an ASP page. It requests three or four recordsets through an MTS database object, but I'll be moving the logic into a COM object and should see the performance improve greatly.

KNOW WHEN TO USE WHICH LANGUAGE

This question keeps coming up, so I thought I should answer it again. Several users have asked whether they can use JavaScript with ASP. Here's the answer: Yes. You can use JavaScript (or any other language that you can install on Windows NT) with ASP. You can use it both on the server and as part of the client page. However, don't expect to find much support for JavaScript on the server. All of the ASP books I've picked up lately use VBScript exclusively on the server. All the support information you'll find at Microsoft's site for ASP is written using VBScript, as are all the examples in the Microsoft Developer Network Library.

However, nearly every book I've seen uses JavaScript on the client side. This is because VBScript isn't supported universally (that is, in Netscape) as a client-side scripting language. JavaScript is supported by both major browsers (and some of the minor ones, as well) and has widespread book and third-party support through Web sites and other support mechanisms.

LEARNING XML

You've probably heard about XML and the great potential it has as the next language for the Web. If you want to try out your XML skills, you can download an XML parser from Microsoft's Developer Downloads section:

http://msdn.microsoft.com

There's also a validation tool that you can use to make sure your code is correct before you send it out. This is a good way to build your skills until the next version of Internet Explorer--which will support XML--is released.

MANUALLY CREATING A RECORDSET

One of the features of the ADO recordset is that it can be created manually. Instead of creating a recordset by way of a database, you can create a recordset, add various types of fields to it, and then add data to it. You can then manipulate it just like a database-created recordset, save it to disk, or pass it back from a component for use in an application.

After you create the recordset object, you can use the Add method of the Fields collection to create new fields for your recordset. When you create these fields, you can specify the data type, the field length, and so on. Once you have the fields added, you can use the Open method to open the recordset for modification. You then use the AddNew method to create a new record, followed by the Update method to commit the record to the recordset. Refer to the ADO Fields collection for more information about this feature.

MICROSOFT DATA ENGINE VS. MICROSOFT ACCESS

While Microsoft Access works reasonably well for small Web sites, it just doesn't have the scalability of SQL Server. However, for most people, SQL Server's price puts it out of reach. Halfway between these two options is the Microsoft Data Engine (MSDE). This product provides better scalability and reliability than Access does, but it doesn't have SQL Server's price tag. For more information on MSDE, go to Microsoft's Web site and download this white paper, which discusses the differences between Access and MSDE:

http://www.microsoft.com/sql/productinfo/Access2000Jet&MSDE.doc

MICROSOFT PARTY LINE ON VBSCRIPT AND JSCRIPT

Want to hear about Microsoft's plans for VBScript and JScript? Read this article by the product manager of the scripting group to learn how Microsoft intends to support both languages and how you should use them yourself:

http://msdn.microsoft.com/workshop/languages/clinic/vbsvjs.asp

MODIFYING A RECORD'S PRIMARY KEY

A user asked if it was possible to modify the primary key of a database record. This depends on how the database table was created. If the database table uses a counter or auto-number field, you won't be able to update the key. However, if the primary key is on a field that is just a number or other modifiable value, changing the primary key is just like changing any other field. Remember that once the change is saved to the system, you'll need to access the record with the new key and not the old one.

MOVE METHODS NOT AVAILABLE

Recently, a user asked why, when he created a recordset, some of the move methods (such as MovePrevious and MoveLast) are not available. The reason for this is that the recordset was created as a ForwardOnly recordset. The other three types of recordsets can use the Move, MovePrevious, MoveFirst, and MoveLast methods. In many cases, you'll just need to do a MoveNext as you loop through a recordset. However, if you need to move around throughout a recordset, be sure to first create it as a different type of recordset.

MTS COMPONENTS MUST BE REGISTERED

We've recently published some tips about using Microsoft Transaction Server with DLLs created in tools like Visual Basic. One thing to remember is that while you can drag a DLL from Explorer into the MTS Explorer, that DLL must be registered with the system (using Regsvr32.exe). If it's not, you won't be able to create objects from your DLL, regardless of whether it's in an MTS package.

NEW TIMER FUNCTION

If you've ever wanted to time your scripts to make sure they don't take too long, VBScript 5.0 has a new feature for you: the Timer function. This function returns the number of seconds that have elapsed since midnight, which lets you easily determine the length of time a chunk of code takes to execute. Here's an example from the MSDN documentation on this new function:

Function TimeIt(N)
Dim StartTime, EndTime
StartTime = Timer
For I = 1 To N
Next
EndTime = Timer
TimeIt = EndTime - StartTime
End Function

This function will return the number of seconds it took to count from 1 to N. This can be helpful if you're doing performance-tuning on your application. Simply wrap checks of the Timer function around the code in question to get the amount of time required for it to execute.

SQL SERVER FOR STRING PROCESSING

As you're probably well aware, VBScript in ASP is relatively slow when it comes to string manipulation. However, if you're doing a lot of string "stitching" using data from a database like SQL Server, you can let the server do more of the work for you. Here's a quick example of this in action: This stored procedure is designed to retrieve the name and URL of a bunch of Web sites that are stored in a database table. Instead of having ASP put the URL together with the name, I let SQL Server do it in the stored procedure. In fact, the only thing that ASP has to do is loop through the records and print out the value of the Web site field. Add a UL tag to the top and bottom, and you've got a bulleted list of Web sites. Here's the stored procedure code:


CREATE Procedure sp_RetrieveClientSites As
SELECT
'<li><a href="http://' + RTrim(URL) + '">' + RTrim(Name) + '</a>' As Web site
FROM tblClientSites
WHERE IsActive = 1
Order By Name
You can see this code in action at this URL:

http://www.northcomp.com/res_clients.asp

OPTIONS FOR ORDERED LISTS

Besides the default Arabic numerals normally used for ordered lists (created with the OL tag), you can create lists that use other number formats to list items. You use the TYPE parameter in the OL tag, along with the following values:


(TYPE=A) - capital letters. e.g. A, B, C ...
(TYPE=a) - small letters. e.g. a, b, c ...
(TYPE=I) - large roman numerals. e.g. I, II, III ...
(TYPE=i) - small roman numerals. e.g. i, ii, iii ...
(TYPE=1) - default numbers. e.g. 1, 2, 3 ...
You can also specify the starting number by using the START parameter. This parameter needs to be used with an Arabic number, as shown here:

<ol type=I start=5>

For this tag, the items will start with Roman numeral 5 (V) and continue from there. This is helpful if you have multiple lists that aren't together or are on separate pages but should be shown as part of the same "outline."

OWNERSHIP OF CODE

Here's a non-technical tip for today. A user asked about ownership of code that he wrote for a client. The basic answer is: It depends on what you negotiated. (You did get a contract, I hope!) Typically, if you work full-time for someone as an employee, your employer owns anything you create. If you're an independent consultant working for a client, it's up to you (and the client).

I will typically give ownership to the client but include provisions that allow me to use the code for other clients, as long as they don't compete directly with the first client. This lets me reuse code in other projects. Whatever you decide, make sure it's on paper. Also, it's a good idea to get in touch with an intellectual property lawyer if you're really concerned about ownership.

PASSING VARIABLES BETWEEN PAGES

A user asked how to pass a "variable" between pages without using the Session object. Without using the Session or Application object, there is currently (IIS 4.0) no way to do this. (Windows 2000 folks, there is a way... hang on a sec.) You can, however, pass data between pages in a number of ways:

Make it part of the URL and accessible through the Request.QueryString collection.
Use invisible form fields that are accessible through the Request.Form collection.
Save the data to a disk file and reopen it in the next page.
Save the data to a database table and open it in the next page.

In Windows 2000 and IIS 5.0, you can use the Server.Transfer method to move some information from one page to another. For instance, any data in the Request object will be made available to the second page. However, local variables that you declare won't be available in the new page.

PERMANENT VS. TEMPORARY COOKIES

If you're using cookies in your application, know whether you're using temporary or permanent cookies. Temporary cookies are cookies that are created without an expiration date, using code like this:

Response.Cookies("MyCookie") = "My Value"

This cookie goes away when the browser is quit. If you need a permanent cookie (for a saved login, for instance), you can set the Expires property like so:

Response.Cookies("MyCookie") = "My Value"
Response.Cookies("MyCookie").Expires = DateAdd("d", 30, Date)

This will give the cookie an expiration date of 30 days. In this case, the cookie will be written to your browser's cookie directory/storage area.

PERSISTING A RECORDSET

In multipage applications, there is often a need to pass a recordset's data from one page to another. Besides passing the SQL statement or storing the recordset in the Session or Application object, you have more options in ADO. You can, for example, save the recordset to a disk file. Once you've saved the recordset, you can reopen the recordset by filename. The Save method of the recordset object allows you to specify a pathname. To reopen a file in another recordset, you specify the pathname in the Open method instead of a SQL string. One thing to remember is that the directory to which you write your saved recordsets must be writeable by your Web server user ID, whatever that happens to be.

READY OR NOT, HERE COMES XML

Not sure how your ASP application fits in with XML? Here's a recent article in Windows NT magazine that explains how the two technologies fit together:

http://www.winntmag.com/Articles/Content/8523_01.html

REMEMBER TO SET COMMANDTYPE

I recently ran into a problem involving an ADO Command object. I was trying to use a stored procedure with SQL Server, but after setting everything, including the parameters, I was getting no results. Of course, the error messages didn't make any sense, either. After reviewing the code, I realized I hadn't set the CommandType property of the Command object. Once I set that, things worked properly. Here's the complete code:

Set cmdQuery = Server.CreateObject("ADODB.Command")
With cmdQuery
Set .ActiveConnection = dcnDB
.CommandType = adCmdStoredProc
.CommandText = "sp_KeywordSearch"
Set parItem = .CreateParameter("Keyword", adVarChar, _
adParamInput, 255, Request("txtKeywords"))
.Parameters.Append parItem
End With
Set rsData = Server.CreateObject("ADODB.Recordset")
rsData.Open cmdQuery, , adOpenStatic

In this case, the stored procedure is named sp_KeywordSearch and takes a parameter called Keyword. The parameter is created and then appended to the Command object. Accordingly, when you open the recordset object, instead of specifying a SQL string, you supply a Command object.

REMOTE ADMINISTRATION

One of the most overlooked features of Internet Information Server 4.0 is its ability to be administered remotely via the Web. Depending on the installation options you use, you may have up to three directories (Web shares) in your default Web site. BOADMIN is the BackOffice Administrator site, NTADMIN is the NT Administrator site, and IISADMIN is the IIS Administrator site. These shares are restricted, by default, to console users only. However, if you've set up the appropriate security, you can allow them to be used by anyone who has permission. You can change the security for each share by using the Security tab in the Properties dialog box.

REMOTELY RESTARTING THE SERVER

Here's a tip on how to create a script to start and stop your Web server without having to be on the console. The script, which follows, will prompt for the server name and whether you want to start or stop the services. The script even works via dial-up connection. Of course, you'll first need administrator privileges on the server.

'This script will Start or Stop the IIS related services on a remote server'

Dim ServerName

Dim ServiceSet

Dim Service

Dim StartStop

 

Sub StopServices()

Set ServiceSet =

GetObject("winmgmts:{impersonationLevel=impersonate}!//" _& servername).ExecQuery("select * from Win32_Service")

For each Service in ServiceSet if Service.Description = "World Wide Web Publishing Service"

then

If Service.State = "Running" Then Service.StopService()

End If

ElseIf Service.Description = "Microsoft SMTP Service" then If Service.State = "Running" Then

Service.StopService()

End If

ElseIf Service.Description = "FTP Publishing Service" then If Service.State = "Running" Then

Service.StopService()

End If

ElseIf Left(Service.Description, 9) = "IIS Admin" then

If Service.State = "Running" Then

Service.StopService()

End If

ElseIf Service.Description = "MSDTC" then

If Service.State = "Running" Then

Service.StopService()

End If

End If

Next

End Sub

 

Sub StartServices()

Set ServiceSet =

GetObject("winmgmts:{impersonationLevel=impersonate}!//" & servername).ExecQuery("select * from Win32_Service")

For each Service in ServiceSet

if Left(Service.Description, 9) = "IIS Admin" then

If Service.State <> "Running" Then

Service.StartService()

End If

ElseIf Service.Description = "Microsoft SMTP Service" then

If Service.State <> "Running" Then

Service.StartService()

End If

ElseIf Service.Description = "FTP Publishing Service" then

If Service.State <> "Running" Then

Service.StartService()

End If

ElseIf Service.Description = "World Wide Web Publishing

Service" Then

If Service.State <> "Running" Then

Service.StartService()

End If

ElseIf Service.Description = "MSDTC" then

If Service.State <> "Running" Then

Service.StartService()

End If

End If

Next

End Sub

 

ServerName = InputBox("Enter the NetBIOS Name of the Server you would like to process")

StartStop = InputBox("Would you like to START or STOP the IIS services? " _

& (Chr(13) & Chr(10)) & "Please Enter 'start' or 'stop'" & (Chr(13)

&

Chr(10)) _

& "OR 'quit' to Exit","Start Or Stop Remote IIS Services","quit")

If lcase(StartStop) = "stop" Then

StopServices

Wscript.Echo "Services Stopped!"

ElseIf lcase(StartStop) = "start" Then

StartServices

Wscript.Echo "Services Started!"

Else

Wscript.Echo "No Action Taken."

End If

SAVING A RECORDSET

One of the features of the ADO Recordset (in ADO 2.5) is the ability to save the recordset to a disk file. There are currently two file formats you can use. The first (and default) is called the Advanced Table DataGram Format. This file format will allow you to reload the recordset by specifying its filename as the source when you open your recordset. Here's the code for saving the recordset:

Dim dcnDB ' As ADODB.Connection
Dim rsData ' As ADODB.Recordset

Set dcnDB = Server.CreateObject("ADODB.Connection")
dcnDB.ConnectionString = _
"Provider=SQLOLEDB;" _
& "Data Source=Server;" _
& "Initial Catalog=DB;" _
& "User ID=user;" _
& "Password=password;"
dcnDB.Open
Set rsData = dcnDB.Execute("SELECT * FROM Customers")
rsData.Save "C:\DataFile.txt"
rsData.Close
dcnDB.Close

To reopen this file, you do the reverse:

Dim rsData ' As ADODB.Recordset
Set rsData = Server.CreateObject("ADODB.Recordset")
rsData.Open "C:\DataFile.txt"
Do Until rsData.EOF
Response.Write rsData("CompanyName") & "<br>"
rsData.MoveNext
Loop
rsData.Close

If you need to save searches, this is a fairly straightforward way to do it: Save the results to a file that you can reload later.

SCHEDULING A PAGE

A reader asked if there's a way to schedule an ASP page to run every month at a specific time. Not knowing the specific purpose our reader had in mind, I'll share a couple of ways to do this.

The easiest way (assuming the Web page didn't require any input) is to schedule a task in Windows to run your browser with the URL as part of the command line (assuming your browser has this ability, which it should). The Windows Task Scheduler will give you a number of scheduling options, including the once-a-month option that our reader requested. You can also do this from the server side, but in that case, it's probably easier to use a stored procedure scheduled through SQL Server. Finally, you can use a client running on the server (instead of the Web page) to do the task.

SCRIPTLESS ASP FILES

In IIS 4.0, it is more efficient to name all static content files (with no ASP code in them) using an .HTM or .HTML extension. This way, the server doesn't have to process them through the ASP engine. However, IIS 5.0 is much smarter about processing these so-called scriptless ASP files, and the server processes these files much more quickly. This means IIS 5.0 users can give all files the .ASP extensions, just in case it's necessary to add ASP code in the future.

SEARCHING LONG TEXT FIELDS IN SQL SERVER

One thing currently done on the ASP Techniques  Web site is store all the content in a SQL Server database. Because of some long text articles, these are stored  in ntext fields. The problem is that in SQL Server, ntext fields are not searchable using the LIKE keyword. This makes performing keyword searches impossible.

However, using the Full-Text Indexing feature of SQL Server, it can support keyword searches. IT will specify the table(s) and field(s) to index, and SQL Server automatically creates a full-text index of those fields. The best part is that the SQL query still uses the same LIKE keyword. It's basically transparent at the SQL level, and since the indexing runs automatically when the system isn't busy, it doesn't put extra work on a busy server.

SHOWING GRAPHS AND CHARTS ON A WEB PAGE

A user asked about the best way to show a graph or chart on a Web page. For this, you basically have three options. First, if the chart isn't really complicated (for example, a simple bar chart), you could draw a graphic and stretch its width or height to a proportional size. The graphic might only be 2 pixels high and 10 pixels wide, for instance--but you could expand it to 60 pixels high and 10 pixels wide to show 30 percent or 30 units.

A second option is to use a Java applet, which can be controlled from your ASP file. There are a number of applets available, both commercial and freeware, to do this. One good source for Java applets is Gamelan:

http://gamelan.earthweb.com/

A third option, if you have the ability to do so, is to use one of many ActiveX controls to show your graph or chart. Like Java applets, there are a number of commercial and freeware controls available. You can get these controls at a number of Web sites, including

ComponentSource

VBxtras

SITE SERVER'S DIRECTMAIL FUNCTIONALITY

A recent article at ASP Today shows you how to use the DirectMail feature of Site Server 3.0 to keep your customers and visitors updated about changes to your site. Here's the URL:

"Keep in Touch with DirectMail"

UPDATING AN ACCESS DATABASE

A user asked me why, when he attempted to upload an Access database in place of an existing one, he got errors indicating that the file was in use by another process. Access is a file-system database, which means that everything dealing with the database is in one file. The problem is that if someone is using a Web page that uses the database, the server locks the database file open. The only safe time you can replace it is when no one is using the database. This generally means stopping the server long enough to replace the database.

Instead of this method, I prefer to create a user interface for updating/modifying/deleting data in the database, no matter which database I'm using. This completely prevents the problem with Access since, thanks to the user interface, I don't need to fix the database directly. The exception would be a database structure change (new tables, queries, etc.). In this case, I stop the Web server, make the changes, and then start the server again. I try to avoid making structural changes on the fly, but on occasion, you have to.

UPDATING COMPONENTS AND MICROSOFT TRANSACTION SERVER

One of the nice benefits of Microsoft Transaction Server  is that you can remove and add components to MTS packages without any rebooting at all. Simply remove the component from the package and add the component to the package again. MTS may at times take 30-60 seconds to release the component, so if it doesn't work right away, try it again later.

USE SERVER.TRANSFER INSTEAD OF RESPONSE.REDIRECT

I do a lot of redirection in my Web applications. A user logs into a page, and an ASP file processes the input. When the user login is validated, Response.Redirect sends the user to the next page. However, in IIS 5.0, the Server.Transfer method can be used for better results. Response.Redirect actually causes a roundtrip from the user's browser to the server. It puts a code in the HTTP header that tells the browser to request the next page. Server.Transfer simply moves from one page to the next without that roundtrip. If you're using the Redirect method of coding and you're on IIS 5.0 (Windows 2000), start changing your code to make it more efficient by using Server.Transfer. Your users will get a better experience with less roundtrips to your server.

USING ACCESS DATABASES WITH ASP

Recently, a few questions about Access databases--and their relation to ASP--have come to my attention. When working with Access databases, one of the first things you have to do is to make sure your database is in a directory that is writeable by the Web server. You can't typically put your database in your Web directory because your Web directory is often marked as read only. Typically, I'll make a separate directory outside the Web site hierarchy and mark it as writeable for my Access databases. Of course, I personally prefer SQL Server, but your mileage and capabilities may vary.

The other question is in relation to which provider to use for hitting Access databases. If you have Access 97 databases, you can use either the Jet 3.51 or Jet 4.0 providers. However, if you have Access 2000 databases, you have to use the Jet 4.0 provider. If you don't control your Web server (such as in a virtual hosting situation), you'll need to check with your provider to see which ADO providers are available on the server.

USING CLASSES IN VBSCRIPT 5.0

One of VBScript's newest features is the ability to use classes, just like in VB or VC++. Here's an article at ASP Today about this new feature, currently available in IIS 5.0 and Internet Explorer 5.0:

http://www.asptoday.com/articles/20000216.htm

USING MTS COMPONENTS WITH ASP

In a previous tip, I mentioned that components you use with Microsoft Transaction Server (MTS) have to first be registered on the server before you can add them to a package. Actually, this is not exactly correct. Granted, it's true that when you use the Import Component feature and select Add Component, MTS lists only the components that are registered. However, the Import Files feature will let you pick a DLL that isn't registered and use it within an MTS package. You can also drag and drop components from Windows Explorer into an MTS package. What's more, MTS automatically registers the components when you add them in either of the latter two methods.

CORRECTION: Previously, we sent this tip with a slight error. The fourth line erroneously read Request(item.Name) instead of Request(item.Value). 

.Here, then, is the tip as it should have appeared:

In an application I'm writing, I have a form that shows a large number of check boxes. These check boxes each become a record in a database table related to the primary entity. To make it easy to insert the appropriate records for the main record, I created a naming structure for each box based on the primary key of the value shown by the check box. Prefixing the name with dbchk then made it easier to find when looping through the Request collection. Once I determine if the box is checked, I call a stored procedure to insert the record into the table. Here's an example of how to check the value, assuming the name is dbchkValue##, with ## being the number of the category.

Dim item ' As Variant
For Each item in Request.Form
If Left(item.Name, 5) = "dbchk" Then
If Request(item.Value) = "Y" Then
dcnDB.Execute("sp_AddRecordToTable " & Mid(item.Name, 11))
End If
End If
Next ' item

This code will automatically insert a row into the table for each check box that is marked. It also saves you from having to write lots of redundant code to insert particular rows into the table.

USING SQL SERVER FOR DATE PROCESSING

As you learned in a previous tip, ASP is slow when it comes to formatting text. In addition, it has too few functions for manipulating dates. For this reason, I decided to let SQL Server handle some of my date work in a page I built listing books I've written. Here's how the final output looks:

http://www.northcomp.com/res_bookstore.asp

and here's the stored procedure I used:


CREATE procedure sp_RetrieveBookList
As
SELECT B.pkBookID, B.Name, B.Description, B.ISBN,
'Publication Date: ' + DateName(month, B.PubDate)
+ ' ' + Cast(Year(B.PubDate) As varchar(4))
As DatePublished,
'/pics/book_' + B.ISBN + '.gif' As BookGraphic,
'<a href="' + RTrim(S.URL) + '">' +
RTrim(S.Name) + '</a>' As WebSite
FROM tblBooks B, tblSites S
WHERE b.fkSiteID = S.pkSiteID
Order By B.PubDate Desc
In this case, I used SQL Server's built-in functions for extracting the month name and year of the publication date. Instead of returning those values, I put them together with the appropriate text and returned the whole thing as a single field. I also stitched the ISBN number with a directory and a file extension to create the local URL to point to the book cover graphic. Finally, I returned the support Web site name and URL together as a single field.

Note that I used a Cast function around the result of the Year function. This is because SQL Server assumes that since you're adding a string (the month name and space) to a number, you must want to convert the whole thing to a number. This causes an error, but using the Cast function eliminates the problem.

If you're working with an affiliate program, such as one run by online bookstores, you can easily create multiple URLs using the book's ISBN number and the affiliate URL provided by your bookstore. Again, leave the string manipulation on the server, where it will run faster.

USING SQL SERVER FOR STRING PROCESSING

As you're probably well aware, VBScript in ASP is relatively slow when it comes to string manipulation. However, if you're doing a lot of string "stitching" using data from a database like SQL Server, you can let the server do more of the work for you. Here's a quick example of this in action: This stored procedure is designed to retrieve the name and URL of a bunch of Web sites that are stored in a database table. Instead of having ASP put the URL together with the name, I let SQL Server do it in the stored procedure. In fact, the only thing that ASP has to do is loop through the records and print out the value of the WebSite field. Add a UL tag to the top and bottom, and you've got a bulleted list of Web sites. Here's the stored procedure code:


CREATE Procedure sp_RetrieveClientSites As
SELECT
'<li><a href="http://' +
RTrim(URL) + '">' + RTrim(Name) + '</a>' As WebSite
FROM tblClientSites
WHERE IsActive = 1
Order By Name
You can see this code in action at

http://www.northcomp.com/res_clients.asp

USING STYLE SHEETS AND SQL FOR OUTPUT

As I've mentioned in previous tips, it's much quicker to manipulate strings within either SQL Server or compil