Activate Your Web Server

Jim Falino

Have you heard? There's a new craze that's sweeping the nation! No, I don't mean Hanson. No, not even Starbucks coffee. I'm talking about the World Wide Web. The Internet. The Information Super . . . ah, you get the point. And with every new "happening" in life, you're confronted with two choices: jump on the bandwagon early, or wait for others to take the plunge first. I don't know about you, but I'm a wait-and-see kind of guy myself. And that's exactly why I feel like it's time to begin writing applications for the Web. The technology has come a long way from the days of plain text, static HTML, and cryptic CGI scripts on UNIX servers. With the advent of Active Server Pages (ASP), a component of Internet Information Server since version 3.0, Microsoft has once again led the way to making our programming lives a lot easier, if not downright fun. In this article, Jim leads you through the basics behind ASP; next month, he'll show you how you can use your favorite tool, Visual FoxPro 5.0, to help build dynamic, exciting Web pages.

Web development has steadily gotten easier as HTML builders like Front Page have entered the market. But to get beyond a very basic Web site, one needs to know how to write client-side scripts in VBScript or JavaScript. That's not too hard, and it will give you the ability to create dynamic Web pages, but it won't allow the user to interact with the server. Common Gateway Interface (CGI) scripts, which are server-side programs, would be required in order to accomplish this task. But CGI has its roots on the UNIX operating system, so many of us Windows developers are unfamiliar with it.

Active Server Pages, on the other hand, takes the best of what Web development was and makes it even better. ASP is a new server-based technology developed by Microsoft and designed to build dynamic, interactive applications for the Web or a LAN-based intranet. It's included with version 3.0 or later of Microsoft's Internet Information Server (IIS), the family of related server products geared toward Web development. At IIS's core is the HTTP server, which is responsible for serving HTML content in response to requests from Web browsers. ASP.DLL, another component of IIS, is called on to interpret scripts and return HTML whenever a file with an .ASP extension is requested from a Web site. You create these script files instead of, or in addition to, static HTML files so that you can add the power of programming to the cross-platform, thin-client model of HTML.

In fact, active server scripting, as the technology is sometimes called because of the server's ability to interact with the client, allows you to seamlessly integrate the following technologies: HTML, client-side scripts (in any language your browser supports), server-side scripts (in any language your Web server supports), and ActiveX components, including data access objects. As a matter of fact, since ASP pages can call any program on the server, you should be able to keep your existing site running while slowly integrating ASP. Now you can do everything that you could with CGI, but in a more familiar fashion.

In this article, I'm going to get you comfortable with all of the major features of ASP, even if you've never had any exposure to Web development. In a subsequent article, I'll show you how to harness this newfound skill to build a simple Web site using a Web browser front-end, a Visual FoxPro middle-tier, and a Microsoft SQL Server database.

An introduction to Web development

Before you write your first ASP program, you need to be up to speed on the basics of Web development. (This will also give you an appreciation for what ASP provides.) HTTP (Hypertext Transfer Protocol) is the standard transfer protocol of the Internet. Its architecture, as well as the constant evolution of HTML, is managed by the W3C Consortium (yes, of course they have a Web site, www.w3.org). The protocol works within a client-server model: A client makes a request of the server, and the server responds to that request. But what separates the HTTP protocol from others used for traditional client-server database applications is that it's stateless. This means that once a client connects to a server, sends its request, and gets its response, the connection is broken and no information about the transaction is retained. (See the sidebar "The Typical Web Browser–HTTP Server Conversation.")

This last point is both good news and bad. Since HTTP is stateless, every request for something from the server must establish a new connection. This means that if your Web page has three GIF files and two Java applets, then five separate, consecutive connections must be made and broken.

While that's an awful lot of overhead (and would make one lousy database application), the fact that you don't have a permanent connection to the server allows your Web site to be "hit" by an almost unlimited user base -- like the world!

Setting the environment

The Web publishing directory that Visual InterDev created for me is c:\webshare\wwwroot\. This is called the virtual directory, and all ASP files must reside within it. Personal Web Server can be launched from Control Panel. From there, you can reset the Web Server home root directory by clicking on the Services tab, HTTP, then Properties. I also created a subdirectory called examples under wwwroot to place my HTML and ASP files in. You should do the same to follow along with the examples given later in this article. My Web server is called http://165.254.101.51; yours will differ. (You can determine this by using the Windows Internet Protocol Configuration program, WINIPCFG.EXE, located in your \Windows directory if you're running Windows 95.)

Make sure that the directory where you put your ASP files is shared. To do this in Windows 95, first right-click on the examples directory under wwwroot and choose the Sharing... menu option. Then, in the Sharing tab of the WWWRoot Properties dialog box, select the Shared As option button. Give it a share name. Then click on the Web Sharing button and make sure the Share Folder for HTTP option is selected, as well as Execute Scripts. Uncheck the Read Only option.

To do this in Windows NT, use the Directory Properties dialog box in the IIS Service Manager's Directories tab.

Helloworld.htm

You're finally ready to create your first Web page. Since it will be very simple, I'll use an equally primitive tool, Notepad, to create it -- just to keep the theme. All you need to do is create a file named c:\webshare\wwwroot\examples\helloworld.htm that contains the following line of text:

Hello, World!

To execute the .htm file, you need to run your browser and enter an address like this:

http://165.254.101.51/examples/helloworld.htm

I'm not going to spend any time teaching you HTML. You can get a Quick Reference at any bookstore, or on the Web, and be programming in minutes. So, without much explanation, I'll dress up this page a little:

<!-- Helloworld.htm -->
<TITLE>My First Web Page</TITLE>
<BODY BGCOLOR="Yellow">
<FONT COLOR="Green">
<b>Hello, World!<b>
</FONT>
<FONT COLOR="Red">
<h1>Is anyone out there?</h1>
</FONT>
<FONT COLOR="Blue">
Testing...<BR>1...<BR>2...<BR>3...
</FONT>
</BODY>

Not rocket science, right? It doesn't take long to get pretty good at this stuff, but it's when you really try to develop a complete Web site that you begin to see the limitations of static HTML and the stateless HTTP protocol.

Tip!

Resist the temptation to just double-click on the helloworld.htm file in Explorer. This will correctly open the file and display it in your browser, but you're not truly using the Web server. Since we're trying to simulate a client-server environment whereby all of these files reside on the Web server, please play along.


Enter Active Server Pages

You'll almost be disappointed at how easy it is to make your first active server page. Just rename the file helloworld.htm to helloworld.asp, change the address in your browser, and refresh the page. If you see no changes, you did great! This illustrates ASP's first feature -- the ability to serve hypertext to a browser just like any HTML file.

Activating the server

Now I'll trim down this static text file and add a little VBScript to show how you can create a dynamic page that responds to something external in the environment, such as the system time when the page was called.

<!-- Helloworld.asp -->
<TITLE>My First Active Server Web Page</TITLE>
<BODY BGCOLOR="Yellow">
<%
If Time >= #12:00:00 AM# And Time < #12:00:00 PM# then
  cMessage = "Good morning, World! How about some coffee?" 
Else
  cMessage = "Hello, World! How's your day going so far?" 
End If
%>
<FONT Size=12 COLOR="Red">
<%=cMessage%>
</FONT>
</BODY>

This HTML/ASP page has two pieces. The first is static HTML text, like the <TITLE>. The second is script that's interpreted by the server when it's called and thus provides dynamic content to the user via his or her browser.

The programming is straightforward; you just need to understand how to integrate the script that will run on the server with the HTML text that will be passed to the browser. Any code that you'd like to run on the server should be enclosed in the delimiters <% … %>. Since you can't specify a scripting language using this syntax, the ASP default (VBScript) is assumed. If, however, you do want to set the default scripting language for an entire ASP file, you can issue the following at the top of the file:

<% @ Language="YourAlternateScript" %>

Also note that you need to prefix output variables with an equal sign (=) for them to execute. This is what the <%=cMessage%> was doing -- outputting the variable cMessage. Knowing which syntax to use might seem a little confusing, but once you're comfortable differentiating HTML, client-side script, and server-side script, this process becomes very easy.

When the programming gets more complicated, you'll need to create entire procedures or functions. You can do this in any scripting language that you desire, as long as the server is running that scripting engine. ASP ships with two easy-to-learn scripting languages that can run on IIS: VBScript and JScript, Microsoft's implementation of Netscape's JavaScript. (Don't confuse this with the fact that you can use these languages for client-side scripts as well by using the HTML <SCRIPT> tag. I'm talking about the server side here.)

In this example, the VBScript function getGreetingMessage is contained in the same ASP file as the function call:

<!-- Helloworld.asp -->
<TITLE> My First Active Server Web Page </TITLE>
<BODY BGCOLOR="Yellow">
Let's have a comment saying that this function
Is contained later in this .asp file
<!-- The contents of the following function -->
<!-- is contained later in the script. -->
<!-- Its return value will be sent to the browser. -->
<%=GetGreetingMessage()%>

<-- HTML portion of this ASP file -->
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
< -- This VBScript function will be run at the server -->

Function GetGreetingMessage
If Time >= #12:00:00 AM# And Time < #12:00:00 PM# then
  message = "Good morning, World! How about some coffee?" 
Else
  message = "Hello, World! How's your day going so far?" 
End If
<!-- This is how you return values from functions in -->
<!-- VBScript. -->
GetGreetingMessage = message
End Function
</SCRIPT>

Essentially, you use the <%...%> for inline server-side scripting. The <SCRIPT> tag can be used on both the server and client sides. On the server side, it would be used for large blocks of server-side code, like VBScript functions and procedures, that are either going to output HTML or support other code in that effort. On the client side, it can be used to dynamically create output HTML as well, but there are more advantages to running it on the server, as I'll show later in the article. So, to differentiate the two, ASP introduced the RunAt attribute of the <SCRIPT> tag so you can specify where you want the script to run.

Server-side include files

Recognizing the fact that developers will want to create libraries of reusable code, the mechanism of include files was added to ASP. Server Side Includes (SSI) are used when you need to insert HTML, plain text, or another ASP file into an ASP file at runtime. You probably already know that an include file is normally added at compile-time, but ASP files aren't compiled, they're interpreted. Thus, the only time an include file can be inserted is right before IIS processes the script file. So, when an ASP file is called, it looks to see if there are any server-side includes within itself. If there are, the code in the include is added to the ASP file before it actually executes. Here's the syntax:

<!--#INCLUDE VIRTUAL|FILE="filename"-->

Virtual means that the file is located in the path beginning with a virtual directory, whereas File means that the file to include is in the path relative to the directory that the including file is in. In other words, if you keep the ASP file and the include file in the same directory, use the File clause and you'll be fine.

The classic example of an include file is to create a header.htm and footer.htm that can be dynamically added to any ASP file so that every page on an entire Web site has the same look and feel. Here, we use both:

<-- Helloworld.asp -->
<TITLE> My First Active Server Web Page </TITLE>
<BODY BGCOLOR="Yellow">

<-- Insert the header HTML file here -->
<!--#INCLUDE FILE="header.htm"-->

<%=GetGreetingMessage()%>

<SCRIPT RunAt=Server Language=VBScript>
Function GetGreetingMessage
If Time >= #12:00:00 AM# And Time < #12:00:00 PM# then
  message = "Good morning, World! How about some coffee?" 
Else
  message = "Hello, World! How's your day going so far?" 
End If
GetGreetingMessage = message
End Function
</SCRIPT>

<-- Insert the footer HTML file here -->
<!--#INCLUDE FILE="footer.htm"-->

Here are the contents of the Header.htm and Footer.htm files:

<-- Header.htm -->
<P ALIGN=Center>
This text goes at the top of every Web page
</P>

<-- Footer.htm -->
<BR><BR><HR>
<P ALIGN=Center>
This text goes at the bottom of every Web page
</P>

As I've said, you can also include an ASP file within an ASP file. Unfortunately, you can't decide at runtime which file you want to include; it's too late at that point. So, the only workaround is to include all the possible files you'll need, and then have the main ASP file only display what's relevant.

The Active Server Pages object model

What I've demonstrated thus far only scratches the surface of ASP. Not only can you write scripts to build dynamic Web pages, there's an entire object model that you can use to maintain a "conversation" between the user and the active server. In other words, by using ASP's objects, the server can "remember" information the user has supplied from the moment he or she accessed the Web site. The connection is still broken, but things like cookies and application- and session-level variables give the illusion that there's still a connection. These objects expose an interface that allows the Web developer to perform the following tasks:

Traditionally, the way one would communicate with a server was through HTML forms. Data entered into a form by a user was submitted to a server CGI program that would, in turn, create an appropriate HTML response. Another way was to append parameters to the end of a URL to create a query string. You might have seen this before while browsing the Net. The URL would look something like this:

http//www.amazon.com?isbn=1-234567-89-0

The Active Server Pages object model enables us to retrieve this information so that it can be used in ASP scripts. The client- and server-side data that can be collected provides the intelligence the developer needs to be able to make flexible, user-interactive Web pages.

The ASP object model forms a hierarchy with the Server object at the pinnacle. The properties and methods of this object can be used to make your scripts even more powerful by providing you with tools to manage your application. The other four main objects, together, round out the Active Server application. These objects are called Request, Response, Application, and Session. Following is a brief look at these objects and some of the more notable properties and methods of each.

Request object

The Request object contains all the information that the client sent to the server as part of the HTTP resource request. The active server parses the information it was passed and publishes it in the Request interface so that it's readily available to you. For instance, you can determine the type of browser that a user is running so that you can dynamically tailor a Web page for him or her:

<-- Request.asp -->
<TITLE>Welcome to My Search Page</TITLE>
<%
<-- Get the browser name -->
cBrowserType=Request.ServerVariables("HTTP_USER_AGENT")
If InStr(cBrowserType, "MSIE") Then
%>
  <!-- It's Internet Explorer -->
  <!-- Show animated IE image and MSFT slogan -->

  <IMG SRC="IE_ANIM.GIF"><BR>
  <CENTER><FONT SIZE=6 COLOR='RED'>
  Thanks for choosing Internet Explorer!<BR>
  Where do you want to go today?
  </FONT></CENTER>
<%Else%>
  <!-- It's NOT Internet Explorer, so don't show IE GIF -->
  <!-- But try to convince them otherwise -->
  <CENTER><FONT SIZE=6 COLOR='RED'>
  Wouldn't you rather be running Internet Explorer?
  </FONT></CENTER>
<%End If%>
<CENTER><INPUT TYPE=Textbox Name=txtSearch>
<INPUT TYPE=Button Value=Go!></CENTER>

This example makes use of the ServerVariables collection -- one of the four collections of the Request object that I'll be addressing. The others are the QueryString, Form, and Cookies collections. The ServerVariables collection contains another 16 members, like PATH_INFO, REQUEST_METHOD, SERVER_NAME, and SERVER_SOFTWARE. As you can see from the preceding example, having access to all of this information allows you to add great flexibility to your Web content.

The Form Collection allows the server to access the data that's entered by the user after a form is submitted. The HTTP METHOD attribute must be set to POST for this to occur. Here's a simple HTML form, FormSSN.htm, that will POST its results to the server:

<-- FormSSN.htm -->
<FORM ACTION="http://165.254.101.51/example/
   FormResponse.asp" METHOD="Post" NAME="frmAvdWorks">
Please enter your age and Social Security number.
<BR>
Age:<Input Type="Text" Name="txtAge" Size=3>
<BR>
SSN:<Input Type="Text" Name="txtSSN" Size=11>
<BR><BR>
<Input Type="Submit" Name="cmdSubmit" 
    Value="Submit Results">
</FORM>

<-- FormResponse.asp -->
Here's the Results...<BR>
You reported your age to be 
<%=Request.Form("txtAge")%>. 
Wow, thanks for your honesty!<BR>
You reported your SSN to be 
<%=Request.Form("txtSSN")%>. 
Be careful with your personal info!

In the last example, the user calls FormSSN.htm (see Figure 1) from his or her browser. The user will now supply his or her age and SSN. Pressing the Submit button causes FormResponse.asp to be called because that's the file I've specified in the ACTION attribute. FormResponse.asp will be responsible for collecting the client age and SSN data now that it's been sent to the server in the HTTP header and has populated the Request object's collections.

Figure 1: An HTML form used to submit data. The HTTP method- GET or POST- determines which ASP collections will be populated.

The QueryString collection works similarly to the Form collection, but it gathers its data from an HTTP GET METHOD instead of a POST METHOD. If the preceding form (FormSSN.htm) is again submitted, but this time with METHOD="GET", the following would be the string that's sent to the HTTP server after entering an age of 33 and a SSN of 123-45-6789:

txtAge=33&txtSSN=123-45-6789&cmdSubmit=Submit+Results 

Since these are actually parameters, the complete URL looks like this:

http://165.254.101.51/example/formResponse.asp?
   txtAge=33&txtSSN=123-45-6789&cmdSubmit=Submit+Results

You can now use the QueryString collection to extract any of the parameters submitted by the form:

<%
cUserAge = Request.QueryString("txtAge")
cUserSSN = Request.QueryString("txtSSN")
%>

The Form and QueryString collections do have one limitation: The information they gather is only retained until the next request is made by the browser. So, there's no way to retain data beyond one request. The concept of the cookie was implemented in the HTTP protocol to satisfy this need to persist data not only across browser requests, but even across browser sessions. A cookie is a token of data that's sent from the server to the browser and is physically stored on the client's hard drive; you can find them in your \Windows\Cookies directory.

You've probably seen cookies implemented on Web sites that require a login and password. Often this information is saved as a cookie on your workstation so you won't have to log in every time. The pieces of information contained in a cookie can be extracted by using the Cookies collection of the Request object. You can use the Expires property of the Cookies collection to force that password to be invalid after the expiration date stamped in the cookie:

<%If Request.Cookies("SitePassword").Expires > Now() Then 
      Response.Write("Access Denied!")
  End if
%>
 
Response object

As you might expect, the Response object complements the Request object by using its methods to send data from the server back to the browser. The two most notable methods are Write and Redirect. The Write method is used to pass a variable or function to the browser as a string. Here's an example:

<%
Response.Write("This is the current time: " & Time())
Response.Write("<IMG SRC=IE_ANIM.GIF>")
%>

Besides being more like real programming, the Response object allows your code to have a neater appearance because you don't have the <%…%> delimiters wrapped around every output variable.

The Redirect method is also quite useful. You use it whenever you want to send the user to a particular URL. For instance, suppose you create a Web page that allows users to download the latest version of your software.  If you were a very large company, you might have multiple Web sites from which one can download. So, based on a user selecting a city from a drop-down list, you can redirect them to an appropriate URL:

<!-- DLCity.htm -->
<FORM ACTION="http://165.254.101.51/example/dlcity.asp" 
  METHOD="Post" NAME="frmExample">

<P>Please select a download site:<P>
<SELECT NAME="DLCity">
<OPTION>New York
<OPTION>Washingtion
<OPTION>Chicago
<OPTION>Los Angeles
</SELECT>

<Input Type="Submit" Name="cmdSubmit" Value="Go to City">

<!-- DLCity.asp -->

<! -- Notice again that I use the Form Collection -->
<! -- of the Response object to retrieve POSTed data -->
<%cDLCity = Request.Form("DLCity")%>
<%cURL = "http//ACMESoftware/Download.htm?" & cDLCity%>
<%Response.Redirect(cURL)%>

As a result, the following URL will be put in the browser's address pane:

http://165.254.101.51/example/ 
  http/ACMESoftware/Download.htm?Washington
Application object

First, I'll define what an ASP Web application encompasses. An application is all of the files that can be referenced in a virtual directory (usually beneath the Web Server root directory) and its subdirectories. You separate different Web applications on a single Web server by making different virtual directories.

The Application object can be thought of in the same way as the application object we typically create in our VFP applications. In VFP, it's common practice to create a custom class with application-level properties and methods. One of those methods usually contains a READ EVENTS and serves as the application's event handler. The class is usually the first object instantiated when the application is started.

The ASP Application object serves a similar purpose, but its scope and duration are much different. It has scope to all users of the application and a duration that lasts as long as the Web server is running. (As I'll discuss later, it's the Session object that's more similar to the VFP application object; its scope is at the user level.)

The two most significant events of the Application object are the Application_OnStart and Application_OnEnd events. As their names imply, these events are automatically fired when the Web server is first contacted and when the application ends, respectively. These procedures, however, don't reside in an ASP file, but in a file called global.asa.

The following line of code in global.asa shows how you create an application-level variable called anVisitors. Think of it as a user-defined property:

 Application("anVisitors") = 0
Global.asa file

Every application can have one global.asa file, and it must be in the Web server's root directory. As I've shown, it's here that you can establish properties with application-level scope, but this file does much, much more. Its extension -- .ASA -- stands for Active Server Application, and gives more insight as to this file's function. It's actually the active server application's event handler. 

By default, whenever the first ASP file of an application is called, or when a user who doesn't yet have a session requests an ASP file, ASP reads the global.asa file (kind of like how a CONFIG.FPW file is read) and the Application_OnStart and Session_onStart events are fired:

<!-- Global.asa -->

<SCRIPT LANGUAGE="VBSCript" RUNAT="Server">
Sub Application_OnStart
  'Enter scripts here that should be executed when 
  'the application starts
  'This is how you create application-level variables
  Application("anVisitors") = 0
  Application("adStartDateTime") = Now()
End Sub
Sub Application_OnEnd
  'Enter scripts here that should be executed when the 
  'application ends
End Sub
Sub Session_OnStart
 'Enter scripts here that should be executed when 
 'a new user enters the application
  Application.Lock
  Application("anVisitors") = Application("anVisitors") + 1
  Application.Unlock 
  Response.Write("This application has been visited "  
     & Application("anVisitors") & " times since " 
     & Application("adStartDateTime") & "<BR><BR>")
End Sub
Sub Session_OnEnd
  'Enter scripts here that should be executed when 
  'a new user exits the application
End Sub
</SCRIPT>

Being the multi-user developer that you are, you probably noticed that we have could have a contention issue when assigning the value of an application-level variable. In order to deal with the possibility of two users simultaneously updating anVisitors, the Application object has two methods: Lock and Unlock. If you don't call the Unlock method explicitly, the Web server unlocks the Application object when the script ends or times out.

Session object

The session object is used to maintain user/session-level state and establish user-level properties across all pages visited. (This is the true equivalent of the VFP-style oApp application object.) When information is stored in a session object, the client that initiated that session is assigned a SessionID. The SessionID property is stored as a Cookie (a global unique identifier) on the client with no expiration date. It's with this identifier that you can follow a user's path through your site.

This script lets a user know how many times he or she been to the current page during this session. It would reside in the ASP file that builds the page in question and would have been initialized in the Session_onStart of the global.asa file.

<%Session("snHomePageVisits") 
  = Session("snHomePageVisits") + 1%>
Boy, you've been to this home page 
  <%= Session("snHomePageVisits")%> times already

The duration of a session with no activity is determined by the TimeOut property. The default is 20 minutes, but it can be set to a lower value by issuing something like this:

<%Session.TimeOut = 10%>

Or you can completely cancel the session by using Session.Abandon. Perhaps you might do this after three unsuccessful attempts at your login screen.

This Session object is actually the second object I've mentioned that maintains state. If you recall, the Application object was able to retain variables or properties across users and for the life of the application. The Session object not only serves the same purpose at the user level, but it's also the place where you'll store references to data access objects. This will be made clear when I introduce ADO in the Server object.

Server object

Think of the Server object as ASP's toolbox, or as a set of utilities that you'll use from the rest of your ASPs. Its interface has a method that allows you to apply HTML encoding to strings (HTMLEncode), a method to apply URL encoding including escape sequences (URLEncode), a method to convert a virtual path to a physical path (MapPath), and a property that allows you to account for infinite loops in scripts (ScriptTimeout). But by far, the Server object's most powerful method is CreateObject.

Being able to instance Component Object Model (COM) objects within ASP opens up an infinite number of opportunities to extend your Web application. You're no longer limited to a scripting language's functionality (or lack thereof), nor ASP's native functionality. You can also leverage COM objects you've already written in Visual Basic, Visual C++, Visual FoxPro, or any other language that can create OLE/ActiveX Automation Servers. The syntax is virtually the same as it is in Visual FoxPro (note that you need the SET keyword to assign the return value to an object variable):

<%Set oObject  = Server.CreateObject("ComponentName")%>

 You can check for success with the following:

<%If IsObject(oObject) Then
   Congratulations, it's an object!
End If%>

You can now reference all of the properties and methods of the registered COM-aware DLL or EXE you've specified in ComponentName through oObject. (You can both read and write, depending on the type of object you wrote. For instance, you can't change the VFP form Class property, but you can change the Caption property.)

Here's a very simple example of using an ActiveX component created in VFP 5.0 and registered as a DLL on the server. This program is called VFPUtils.prg. (You'd obviously never use VFP for such a purpose, but the example does illustrate how to expose VFP to ASP.)

*!* VFPUtils.prg
Define Class VFPUtils AS Custom OLEPUBLIC
  Name = "VFPUtils"

  Function GetDateTime
    Return DateTime()
  Endfunc
EndDefine

The VFPUtils DLL can be instantiated from within an ASP file so that the DLL's methods can be accessed:

<%Set oVFPObject 
  = Server.CreateObject("VFPUtils.VFPUtils")%>
<%If IsObject(oVFPObject) Then
  Response.Write("The current date and time is: 
      " & oVFPObject.GetDateTime())
 End If%>

Another benefit CreateObject offers is the ability to work with data. Remember, there's no way to access a database with scripting languages, but you can instance any COM-compliant data access object to fill that void. Here's an example of how you can retrieve data from SQL Server though ODBC using Active Data Objects (ADO), which ships with IIS 3.0:

<%
Set oConnection  = Server.CreateObject("ADORecordSet")
oConnection.Open("DSN=PubsSamp;UID=SA;PWD=;DATABASE=Pubs")
Set oRS = oConnection.Execute
  ("Select au_fname, au_lname from authors")
Response.Write oRS("au_fname) 
Response.Write oRS("au_lname) 
%>

Regarding state, you can see that the oConnection variable will fall out of scope as soon as the script ends. Unfortunately, that will break the connection to SQL Server, and the recordset object will be lost. To persist this data for the life of the session, I'd need to create a Session object variable and assign the Server.CreateObject("ADORecordSet") object return value to it. I'll be doing that and much, much more with ADO next month.

Conclusion

It's almost impossible to do this topic justice in such an abbreviated fashion, but I hope I've at least opened your eyes to the world of Web development using Active Server Pages. As you can see, it isn't very difficult to get up and running and begin prototyping dynamic, interactive Web sites immediately.

Next month, I'll focus on using ASP to instance a Visual FoxPro ActiveX Automation server for the purpose of retrieving data from SQL Server and creating the HTML that's to be returned to the browser. I'll also cover error trapping, performance, and scalability issues with ASP. See you next month.

Jim Falino has been happily developing in the Fox products since 1991, beginning with FoxBASE+. He was a developer and trainer for MicroEndeavors in Philadelphia, where he wrote applications for Fortune 500 companies. Most recently, he has returned to his roots, the Big Apple, with his wife and two cats, where for the past two years he's been developing a very large client-server apparel-manufacturing application for the GARPAC Corporation using Visual FoxPro as a front-end to any ODBC-compliant SQL back end. 71421.3462.compuserve.com, jim@garpac.com.

Sidebar: The Typical Web Browser-HTTP Server Conversation Sidebar: Tools of the Trade

The easiest way to get started is to install all components of Microsoft's Visual InterDev. It does most of the setup work for you, including installing Personal Web Server if you're running Windows 95. Personal Web Server provides most of the functionality of Internet Information Server, including the ability to publish Web pages on the Internet or over a LAN on an intranet and Microsoft ActiveX support.

If you're running NT Server 4.0, you've got IIS, but it's only version 2.0. You can download the latest version of IIS -- 4.0 -- at www.microsoft.com/iis. Here are the locations of some of the documentation that Visual InterDev provides and some other references to get you started:

Sidebar: Some New Terms

Let me clear up two terms that are used in new ways for Visual FoxPro developers: An interface is a term used to describe the properties and methods that a particular object chooses to expose, and collections are nothing more than arrays with groups of pairs. The first part of the pair is called the key, and the second is called the value. By requesting a key, a value is returned. If VFP had collections, it would take the place of having to perform an AScan() and then an ASub().