Essential ASP Hints and Tips
Near the start of last year, I posted a thread in the SitePoint Forums about tips and techniques I used when coding ASP. Since then there have been many amendments and additions to the thread, which I’ve included here.
One recurring statement in discussions of ASP vs. PHP is that PHP is faster. Now, I might be branded a traitor, and be sent threatening emails for saying this, but I sometimes agree. PHP can be faster than poorly written ASP.
There are so many ways of doing things in ASP that sometimes it’s easier to pick the wrong approach rather than the right one. And new solutions are always being developed: only recently did I learn one of the tips below. Everyone, as far as ASP goes, seems to have a different way of doing things, and we can’t all be right. I’m not saying that I’m right and you’re wrong; this is simply what works for me. If you have alternative suggestions, send them in! Ok, let’s get started!
Colons
Near the end of last year, I stumbled on this little jewel. As far as I know, it won’t affect the performance of your scripts at all. Colons allow you to condense code that would span a number of lines to just one line. Below you can see and example of this.
Set objDBCon = Server.CreateObject("ADODB.Connection")
strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
Server.MapPath("./data.mdb")
objDBCon.open strConnect
Using, colons, we can shorten the code:
Set objDBCon = Server.CreateObject("ADODB.Connection") : strConnect =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
Server.MapPath("./data.mdb") : objDBCon.open strConnect
Updating PWS
When I started coding ASP I used Windows 98 with PWS as my development platform. Compared to what I use now (Windows .NET Server, IIS6) is like comparing a sheep to a car… But it was all I had at the time, and I was grateful. But one really annoying thing was that PWS was a cut down version of IIS4, which meant you had to code with ASP 2.0. Tired of missing out on all the cool features of ASP 3.0, I went looking for a way to upgrade it.
I eventually discovered that by upgrading the WSH (Windows Script Host), some ASP 3.0 functionality could be accessed using PWS. Bear in mind that not all the functions in ASP 3.0 are available: what you’re actually doing is upgrading VBScript, not the actual ASP.DLL file (so you’ll miss out on the updates to the response, request, server, etc. objects). This means that functions like server.execute
, and server.transfer
(among others) are not available.
The most up-to-date version of WSH at the time of writing is 5.6. To find out quickly what version you have, try this code:
<%
s = ScriptEngine & " Version "
s = s & ScriptEngineMajorVersion & "."
s = s & ScriptEngineMinorVersion & "."
response.write(s)
%>
If this returns anything lower than 5.6, you should upgrade now!
Eval() Tag
If you know JavaScript, you will know that the Eval()
function has been around for a good number of years, both on the client-side and server-side. This function was made available to VBScript developers who had version 5, and shipped with Windows 2000.
What does it do? Well, if you’ve used it with JavaScript, then you already know. It evaluates a string to return true or false. Make sense? No? Well, here’s a quick example.
<%
evalString = "meetingTime = time()"
meetingTime = request.form("meetingTime")
response.write(evalString)
%>
You should all know what the script above does: it should simply return the evalString
to the browser:
meetingTime = time()
But if we used the Eval() function like so:
evalString = "meetingTime = time()"
meetingTime = request.form("meetingTime")
response.write(eval(evalString))
The evalString
would be evaluated to true or false depending on whether the values match.
Executing Statements
The Eval()
function
is all well and good if you need to return true or false, but what about if you have a some ASP you want to execute, like a function or sub-routine? Well, you can! The execute()
function lets you execute whole lines of code! Try this:
<%
executeString = "Sub checkMeeting(timeOfMeeting)" & vbcrlf _
& " If ( eval(meetingTime = time()) ) then" & vbcrlf _
& " response.write(""Meeting!!"")" & vbcrlf _
& " else" & vbcrlf _
& " response.write(""No meeting"")" & vbcrlf _
& "End If" & vbcrlf _
& "end sub" & vbcrlf
execute(executeString)
' loads of code here...
checkMeeting(request.form("meetingTtme"))
%>
What does this mean? Not only can you include dynamic content on your site, but dynamic ASP as well…
With
The "with
" construct is new to VBScript 5, and allows you to define properties of an object at the exact same time the object is created, without requalifying the object. Let’s have a look at it:
with object
.property = "with this value"
.property2 = "also with this"
doSomething = .execute
end with
Now, practically? Let’s create a recordset:
Set RS = Server.CreateObject("ADODB.Recordset")
With RS
.CursorLocation = 3
.Open "SQL statement", connectString
.PageSize = 3
.AbsolutePage = CurrPage
End With
Text Dates
Here’s a quick one! There are two functions that you can use to return the text version of a month and day of the week, MonthName()
and WeekDay()
. These two functions have been around since version 2 of VBScript, but I’ve come across a good many people who didn’t know they existed.
They’re pretty simple:
Response.write(MonthName(month(date())))
Response.write(weekday(date()))
Is An Object?
I’ve got a script that, when called, checks to see of a connection to the database has been made, and if it hasn’t, it makes one (and vice versa). It does this by checking if the variable I use is an object.
I use two functions for this: isObject()
and typeName()
. These functions have been around since version 1 and 2 of VBScript respectively. The isObject()
function returns a Boolean, and typeName()
returns a string.
How can you apply it? Like this:
Dim objDBCon
Public Function connectDB()
On Error Resume Next
If ( NOT isObject(objDBCon) OR _
cStr(typeName(objDBCon)) = "Nothing" ) then
Set objDBCon = Server.CreateObject("ADODB.Connection")
strConnect = "connect details"
objDBCon.open strConnect
else
objDBCon.close : Set objDBCon = nothing
end if
If ( err.Number <> 0 ) then
response.write("<font face=""tahoma"" color=""red""
size=""-1""><strong>There seems to be a problem with
the database. Please bear with us while we repair
it.<br /><br />We apologise for any inconvenience
this may cause.</strong></font>")
response.end
end if
End Function
User Still There?
Every page I develop calls the below sub-routine. What this does is use the isClientConnected
method of the response object. This method returns a boolean stating if the client is still waiting for the response. The function checks this, and if it returns false, it clears and ends the response. It’s pretty handy for those "who’s online" scripts, and saving resources before a large data retrieval!
Public sub checkClientConnect()
If ( NOT response.IsClientConnected )
thenresponse.clearresponse.endend ifEnd Sub
Server.transfer()
Introduced in ASP 3, this was designed to replace Response.Redirect()
. The Response.Redirect()
tells the browser to load a different page, and because of this, the browser has to request two pages. This makes the server process two pages, and creates two round trips from client to server.
Server.Transfer()
is designed to make up for this by simply executing a different script without letting the browser know about the change. Use it the same way asResponse.Redirect()
, with the limitation thatServer.Transfer()
cannot transfer execution to a page on a different server.
Server.Transfer("pageName.asp")
Server.Execute()
Also introduced with ASP 3, the Server.Execute()
works like an include file. But unlike an include file, it is processed as the page is interpreted, meaning that it can be used more efficiently with If...End If
statements.
But what exactly does it do? It shifts server execution to another page, and when that file is finished, it returns execution to the original page. This means that pages aren’t automatically included as with server-side includes (SSI).
Buffering
Buffer pages. Nice and simple: turn the response buffering on, which it is in ASP 3 by default. This will cut down on the number of times data is sent to the client, which will improve overall performance. TCP/IP works much more efficiently when it can send a few large blocks of data, than when it has to send many small blocks, because of its relatively high packet overhead.
How to do it? Before anything is sent to the client, add this line:
<%response.buffer = True%>
Flushing
With buffering on, it appears to users that ASP runs slowly (could this be why PHP seems to run faster?), which it isn’t, of course. It’s simply waiting for the whole page to load before sending it to the browser, which does work out faster in the long run. But because the user is presented with a blank page for a few seconds, it seems slow.
You can counter this, and choose when to send data to the client, using the flush command, which looks like this:
response.flush()
When this is called, everything from the start of the page, or since the last time the page was flushed, is dumped to the browser.
Iterating Through a Database More Quickly
Looping through a bunch of database records and displaying them is something I imagine you have to do a lot. If you don’t yet, then I promise you will someday.
Now, you probably learned to use this technique or something like it:
Set getData = objDB... ' get data from database
Do Until getData.EOF
response.write("<p>Name: " & getData("name") & "<br>" & vbcrlf _
& "Age: " & getData("age") & "<br>" & vbcrlf _
& "Position: " & getData("position") & "</p>" & vbcrlf)
getData.MoveNext
Loop
Look familiar? Thought so…
Now let’s make it faster and more efficient!
Set getData = objDB... ' get data from database
Set name = getData("name")
Set age = getData("age")
Set position = getData("position")
Do Until getData.EOF
response.write("<p>Name: " & name & "<br>" & vbcrlf _
& "Age: " & age & "<br>" & vbcrlf _
& "Position: " & position & "</p>" & vbcrlf)
getData.MoveNext
Loop
But why is it faster? Because, in the loop we don’t have to specify what field we want to access — it has already been done, and the data has already been referenced!
Check If an Object is Available on the Server
by Nikos Liokalos
This function checks whether an object is available on the server.
Function CheckObject(obj)
Dim msg
On Error Resume Next
CreateObject obj
If Err = 0 then
msg = "OK"
else
msg = "Error:" & Err.Description
end if
CheckObject = obj & " - " & Msg & "<br>" & vbCrLf
set obj = nothing
End Function
You can use it like this:
Response.write(CheckObject("ADODB.Recordset"))
Response.write(CheckObject("Scripting.FileSystemObject "))
…or to check any other object needed for your application.
This tip contributed by Nikos Liokalos. Nikos holds a Computer Science degree and an MSc in eCommerce Technology. His interests lie in the Content Management and ecommerce area, and in his spare time he updates his own Web space.
Conclusion
As I mentioned at the beginning, there are any number of ways to achieve specific ends with ASP. What I’ve presented here are just a few techniques that I use to get things done — but feel free to send your own ideas in!
I hope you have fun using the techniques I’ve covered, and most of all, I hope you enjoy coding ASP!