Microsoft Office FrontPage 2003 Inside Out
This article is an excerpt from Microsoft Office FrontPage 2003 Inside Out from Microsoft Press (ISBN 0-7356-1510-1, copyright Microsoft Press 2003; all rights reserved). The author, Jim Buyens, is a FrontPage MVP and a noted expert on Web programming and networking. He develops Web-based business systems for the telecommunications industry and has written several books, including Microsoft FrontPage 2002 Inside Out, Faster Smarter Beginning Programming, and Web Database Development Step by Step .NET Edition, all from Microsoft Press.
No part of these chapters may be reproduced, stored in a retrieval system or transmitted in any form or by any means—electronic, electrostatic, mechanical, photocopying, recording or otherwise—without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews.
Web sites built only of HTML pages and browser-side scripts are one-way conduits. They send information to your Web visitors but receive almost nothing in return. If you want your site to receive, process, save, and react to information from your Web visitors, you'll need to either sit by your Web server 24 hours a day (and be a very fast typist) or develop some sort of program to handle the interactions for you. Of course, most developers choose the latter option and learn to write programs that run on the Web server.
In terms of capabilities, programs on a Web server can do anything more conventional programs can do: check security, query and update databases, send e-mail, capture pictures, read hot tub temperatures, ring bells, toot whistles, and whatever else you can imagine. In terms of interaction with the Web visitor, however, the techniques are fairly rigid:
- The browser sends a request to a program on the Web server. Typically, this includes information from an HTML form or appended to the program's URL.
- The Web server runs the program that the browser requested.
- The program does whatever work the application requires and then, as a response, sends a customized Web page to the visitor.
Designing the HTML for these customized responses involves a dual mind-set. Typically, most of the HTML is the same for each response, and designers prefer a visual editor like Design view in Microsoft Office FrontPage 2003 for this part of the work.
From a programming point of view, server-side scripting eliminates many browser compatibility issues. There's no need to write code that works on many different browsers; you only need to write code that runs on one computer: your Web server. In addition, control is greater. All Web visitors receive information on the same basis—the server's date, for example—and visitors never see script code. Visitors can't turn off the script in their browsers.
This brief chapter can't possibly take the place of a complete book (or library) on Web programming techniques, but it should at least get you into the mind-set and help you understand where FrontPage fits in.
Given the wide range of other technologies found on the Web, it's no surprise that a variety of server-side programming approaches have arisen. Table 42-1 lists some of the most common, along with their proponents and typical programming languages.
Table 42-1. Web Server Programming Technologies
|Acronym||Name||Proponent||Typical programming languages||Works with visual editors|
|ASP.NET||Active Server Pages .NET||Microsoft||Visual Basic .NET, C#||Yes|
|JSP||Java Server Pages||Sun||Java||Yes|
|PHP||PHP: Hypertext Preprocessor||Apache Software Foundation||PHP||Yes|
|ISAPI||Internet Server Application Programming Interface||Microsoft||C++||No|
|NSAPI||Netscape Server Application Programming Interface||Sun||C, C++||No|
|CGI||Common Gateway Interface||National Center for Supercomputing Applications||C, C++, Perl||No|
In this table, notice that ASP, ASP.NET, JSP, and PHP can all make use of visual editors like FrontPage. The developer uses a visual editor to create the overall page design and any fixed elements and then writes code to generate HTML for the variable portion of each response. Of course, the visual design must provide some sort of object or placeholder to indicate where the variable output should appear.
ISAPI, NSAPI, and CGI programs consist entirely of code and must therefore generate every scrap of HTML they send to the Web visitor. Use of these technologies to develop individual Web pages is rare; they're best suited for system software that extends the overall capabilities of Web servers.
Regardless of how you write them, server-side scripts must reside in an executable directory, and for reasons of security and resource consumption, many server administrators tightly control access to such directories.
Note If you don't administer your own Web server, you might need to contact the server administrator to get permission to run server-side scripts.
The remainder of this chapter will describe the ASP and ASP.NET approaches to developing server-side programs and explain how FrontPage fits into that process.
This technology was Microsoft's first attempt to make scripting on the Web server as easy as scripting on the browser. By almost any measure, it's been spectacularly successful. ASP pages quickly achieved number one status as the leading technology for writing server-side scripts that run on Microsoft Web servers.
Note ASP is available only on Microsoft Web servers. If your Web server uses different software, contact the server's administrator for information about alternative approaches. Third-party implementations of ASP are available for UNIX, but they aren't 100% compatible with Microsoft ASP.
The basic ASP paradigm is quite simple. When the server gets a request for an ASP Web page, it processes the page, executes the server-side script, and sends only the results to the visitor. The results consist of plain HTML and not the original script statements.
The script code can appear anywhere in the Web page, but it must be within either of these special tags:
- <script runat="server"> and </script> These tags delimit a code declaration block. The server saves up any script statements you enclose with these tags and runs them when it encounters the end of the Web page.
Few, if any, developers use these tags in ASP pages. This is because any code the tags enclose runs after the body of the page has left the server, and that's too late to customize the page.
- <% and %> These tags delimit a code render block. Any statements they enclose execute immediately. Virtually all real-world ASP code resides between such tags.
Each ASP page executes as one program. This means that in general, any variables you declare in one <% %> block are available in all subsequent <% %> blocks. (Of course, any variables you declare within a subroutine or function are available only within that subroutine or function.)
Note Server-side scripts and browser-side scripts can co-exist. There's no restriction against using server-side and browser-side scripts on the same page. The two script types are identified differently in the HTML, allowing the server-side script processor to pass browser-side script statements to the browser unmodified. Server-side scripts can even generate browser-side scripts by writing the necessary statements to the outbound HTML stream.
Whenever an ASP page is running, it automatically has access to the five objects listed below. A high percentage of the work that ASP pages perform involves manipulation of these objects.
- Request Provides information about the Web visitor's current request.
- Response Sends a Web page or other response back to the Web visitor.
- Server Provides access to information and resources located on the Web server.
- Session Stores information about multiple requests from the same Web visitor.
- Application Provides shared information for all visitors using the same application (that is, using ASP pages in the same designated folder tree).
VBScript has no built-in capability to access databases, read and write files, or send e-mail. To perform these tasks, ASP programmers generally use objects from these collections:
- ActiveX Data Objects (ADO) Objects from this collection access and update databases.
- Scripting.FileSystemObject Objects from this collection access and update files on the Web server.
- Collaboration Data Objects (CDO) Objects from this collection send e-mail.
Note For information about configuring Microsoft Web servers to run scripts, see Appendix O, "Installing and Configuring a Web Server."
Changing Content with ASP Code (Coding Example 1)
This section will illustrate a server-side solution to one of the problems posed in the previous chapter—the problem of displaying New! and Upd! icons for a specified period of time. This solution uses VBScript and the ASP feature of IIS. Figure 42-1 shows the results.
The code to set the first item's picture is shown here:
1 <% maxdays = 14 %> 2 <% If (now - #5/15/2003# < maxdays) Then %> 3 <img src="../images/new.gif"> 4 <% Else %> 5 <img src="../images/cyanball.gif"> 6 <% End If %>
Figure 42-1.This Web page is very similar to the page shown in Figure 41-5, but it uses server-side scripting. The file extension is .asp rather than .htm, and the page resides in an executable directory.
Four features of VBScript make this code somewhat simpler than the Java Script version:
- The now function in VBScript returns the current date and time.
- Dates and times in VBScript are stored as whole numbers for days and fractions of a day for time—6:00 AM is 0.25, 12:00 noon is 0.5, and 6:00 PM is 0.75, for example. Subtracting two dates immediately provides the difference in days.
- VBScript directly supports date values. VBScript treats anything you enclose in pound signs (#) as a date.
Given these features:
- Line 1 in the listing above defines a variable that gives the cutoff period in days: 14.
- Line 2 subtracts the date 5/15/2003 from the current date, giving the difference in days, and then compares the difference to the cutoff period.
- Line 3 is ordinary HTML that the server transmits to the browser only if the If condition is true (that is, only if 5/15/2003 is within 14 days of the current date).
- Line 4 is an Else statement that negates the If statement on line 2.
- Line 5 is ordinary HTML that the server transmits to the browser only if the If condition on line 2 is false.
- Line 6 terminates the If condition.
Figure 42-2 shows the Web page of Figure 42-1 open in FrontPage. Line 1 from the preceding listing resides in the <head> section and doesn't appear in WYSIWYG view. Each category row begins with three VBScript components containing the If, Else, and End If statements from lines 2, 4, and 6, respectively. Lines 3 and 5 of the listing appear as ordinary HTML, which accounts for the appearance of the picture bullets.
Figure 42-2. This is how the Web page from Figure 42-1 appears in FrontPage. The three VBScript components preceding each category item contain If, Else, and End If statements so that visitors see only one icon.
Figure 42-3 shows the same Web page open in Code view. You can see the maxdays = 14 statement just before the </head> statement, and one of the If. . .Else. . .End If sequences that control the bullets.
To add additional categories, the designer would copy a set of three VBScript components and two icons from an existing row, double-click the first icon to set the date, and change the icon file name to new.gif if necessary. To flag a category as updated, the author would change the icon file name to upd.gif if necessary and then double-click the first component to reset the date.
Figure 42-3. Here are the contents of the first VBScript component in row 1, column 1 of the category table in Figure 42-2.
The last Script component on the page displays the current date. The code required to do this is quite simple:
<%=formatDateTime(Now, vbLongDate) %>
Within an ASP page, an expression containing a start <% tag, an equal sign (=), a VBScript expression, and an end %> tag all on the same line is equivalent to one line of code that begins with a document.write statement. (That is, it evaluates everything between <%= and %> as a VBScript expression and inserts the result into the HTML stream.) Type conversion is automatic in VBScript, so <% = now %> would display the current date and time in a default format. The expression shown displays the current day and date with the month in words. The name vbLongDate is a constant built into VBScript.
Debugging Server Scripts with Microsoft Script Editor
Microsoft Script Editor can interactively debug server-side scripts, but it has no remote debugging capability. To interactively debug an ASP page, you must run Internet Explorer, Script Editor, and IIS all on the same computer. In practical terms, the best platform for debugging ASP scripts interactively is likely to be Microsoft Windows XP Professional.
To enable server-side debugging, the server's administrator must select the Enable ASP Server-Side Script Debugging check box on the Debugging tab of the Application Configuration dialog box, as shown in Figure 42-4. This dialog box is part of the IIS snap-in for Microsoft Management Console (MMC).
Figure 42-4. To debug a server-side script, you must enable debugging on the Web server.
To start a debugging session for an ASP page, you must first use a browser to request the page. Then one of two things must happen that interrupt script processing:
- An error If the ASP processor detects a server-side scripting error and debugging is enabled, it starts Script Editor immediately.
In either case, Script Editor will automatically display the page and the statement that caused the interruption.
Script Editor can display several specialized debugging windows in addition to those that appear automatically. You can hide or display these windows by choosing options on the View menu or by clicking toolbar buttons. Figure 42-5 shows how to locate these options.
Figure 42-5. Microsoft Script Editor can interactively display values, modify values, and trace the flow of execution in an ASP page.
- Breakpoints Displays a current list of statements where script processing will halt.
- Running Documents Lists two groups of Web pages. To debug any listed document, double-click its entry:
- Microsoft Internet Explorer Lists any Web pages currently displayed in your browser. Note, however, that double-clicking an ASP page under this entry loads only the code that Internet Explorer receives (that is, the response HTML and any browser-side scripts it contains).
- Autos Lists the name, value, and type of each value in the current statement and the previous statement.
- Locals Displays the values of all variables available to the current script.
- Watch Displays a list of all variables you've instructed the debugger to monitor.
- Immediate Accepts typed commands and displays the results. You can use this window to query or modify variables and properties in your script or to run hand-entered script statements.
To display a variable or property in VBScript, enter a question mark, a space, and the name of the variable or property.
- Call Stack Lists any subroutine or functions that are currently running.
- Processes Displays a list of applications currently running on the server.
- QuickWatch Displays the value of the currently selected expression.
Starting an ASP debugging session is a somewhat indirect process, and it might cause the browser to time out. To understand why this is so, consider the flow of control:
- The browser requests the page.
- The Web server detects a serious error or a Stop statement and finds that server-side debugging is in effect.
- The Web server halts the script.
- The Web server looks for a running copy of Script Editor. If it finds one, it tells Script Editor to start a debugging session. If it can't find a running copy of Script Editor, it starts one and proceeds as before.
- The developer debugs the Web page.
- The browser either times out or displays the resulting Web page, depending on how long the developer spends debugging.
As part of its .NET Framework initiative, Microsoft has released a major upgrade to ASP. This is, of course, Microsoft ASP.NET. The new version reflects several years of experience and enhancement, and it differs considerably from the older ASP technology. Here are some of the limitations ASP.NET resolves:
- VBScript isn't suited for developing reusable modules. To use the same code in several pages, you must copy it into each page.
- Neither ASP nor VBScript has access to the full functionality of the underlying Windows operating system.
- The practice of putting program code where its output should appear in a Web page doesn't scale well. In complex pages, code can end up in all sorts of odd places.
- At many large sites, Web page designers and Web page programmers are two very different groups of people. With the page design and the program code both residing in the same file, conflicts and confusion inevitably arose.
ASP.NET resolves these issues in the following ways:
- ASP.NET uses the full Visual Basic .NET programming language. This is the most capable and most feature-complete version of Visual Basic ever released. You can also code ASP.NET pages in C# or any other language that has a .NET compiler.
- Visual Basic .NET, C#, and other supported languages have access to the entire set of .NET system-level objects. Essentially, this means that an ASP.NET page can do anything Windows can do.
- All .NET programming languages are fully object-oriented. This means that they have access to class libraries and other forms of reusable code.
- ASP.NET clearly separates program code from Web page layout code. You can even store the two kinds of code in different files and then change one without changing the other. You can still mix program code and HTML code if you want to, but after you become accustomed to the new structure, you'll seldom if ever have the desire.
- With ASP.NET, you can create your own program objects—with methods, properties, and all the other accoutrements you want—in essentially the same way that you create Web pages.
ASP.NET also changes the fundamental paradigm for running server-side code. ASP ran code in (and inserted content into) each part of the Web page as it left the server. ASP.NET, on the other hand:
Reads the whole page into memory, storing each HTML tag you want to modify as an object.
More specifically, ASP.NET loads any tag containing a runat="server" attribute into memory as an object. This can be any type of tag, regardless of whether it normally supports a runat="server" attribute.
- Fires a series of events. Some of these occur because of something the Web visitor did, such as clicking a button, and some occur every time a page runs. Designated subroutines (event handlers) in your code respond to these events and can raise additional events of their own. Table 42-2 list the events that occur during each execution of a page.
- Converts the page from a collection of objects back to HTML and transmits this result to the Web visitor. Each object has the opportunity to send whatever HTML it wants to the Web visitor, regardless of the HTML that created the object. For example, none of the objects send the runat="server" attribute to the browser.
Table 42-2. ASP.NET Page Events
|Init||Page_Init||Occurs when ASP.NET initializes the page. No page elements are available at this time.|
|Load||Page_Load||Occurs when ASP.NET has loaded all server controls into memory.|
|PreRender||Page_PreRender||Occurs when ASP.NET is ready to render the page as HTML.|
|Unload||Page_Unload||Occurs after ASP.NET has removed all server controls from memory.|
Another unique aspect of ASP.NET pages is that by default, every page is an HTML form, and that <form> tag has the runat="server" attribute. This is because ASP.NET uses hidden form fields to remember the state of the page from one execution to the next. The presence of <form> and </form> tags when you don't expect them might be a surprise, but they do little harm, and you shouldn't remove them. The way ASP.NET uses forms does, however, lead to two restrictions:
- Each page can contain only one HTML form.
- Each HTML form must request the page that contains it. You can't, for example, use one Web page for data entry and another for processing.
If you want your application to behave as if these restrictions weren't present, you can do so using other techniques. Upon receiving a request, for example, the server-side code for one page can transfer control to another page. These techniques, however, are beyond the scope of this book.
Changing Content with ASP.NET Code (Coding Example 2)
To visualize how some of this works, consider the task of displaying the current date on a Web page, as the Art List example in the previous chapter did, or as the Movie List example in this chapter does. Both of those examples included a line of code where the date was supposed to appear. To use the ASP.NET approach for this task, you would add a tag like the following where you wanted the date to appear:
<asp:literal id="litTodayIs" runat="server" />
Because this tag contains a runat="server" attribute, ASP.NET loads it as an object each time the page executes. The id= attribute gives the object a name. The slash (/)just before the closing angle bracket (>) takes the place of an </asp:literal> end tag.
When ASP.NET sends the page to the visitor, this object supplies the contents of a property named Text. So, if the page contains this statement:
litTodayIs.Text = Now()
the Web visitor will receive the current date and time in place of the <asp:literal> tag shown above. The Page_Load event handler is a common place for such a statement, because Page_Load occurs after ASP.NET has loaded all the objects in the page, and before ASP.NET sends any output to the Web visitor. The first few lines in the Web page might therefore be:
1 <%@ Page Language="vb" %> 2 <script runat="server"> 3 Sub Page_Load (sender As Object, e As EventArgs) 4 litTodayIs.Text = Now() 5 End Sub 6 </script>
Line 1 is a @ Page directive, which sets compile and run-time options for the page. Lines 2 and 6 mark the limits of a code declaration block (that is, an area that contains executable code). Lines 3 and 5 mark the beginning and end of the Page_Load subroutine, which, by virtue of its name, runs every time the Page_Load event occurs. The sender argument points to the object that raised the event (in this case, the Page object), and the e argument points to an object that contains any special information related to the event (in this case, none). Line 4, of course, does the work.
The task of conditionally displaying a New! or an Upd! icon rather than a round bullet is more interesting. Wouldn't it be great to have an HTML tag that displays either of two pictures, based on the interval from some starting date? Well, how about a tag like this?
<fp11iso:datedImg id=" dimgBaseball" runat="server" src1="ballcyan.gif" src2="new.gif" start="4/4/2003" duration="14" />
The src1 attribute specifies the name of the picture that the tag will normally display. The src2 attribute specifies an alternative picture. The start attribute specifies when to start showing the alternative picture, and the duration attribute specifies the number of days to continue displaying it.
As it happens, ASP.NET is great at this sort of thing. The preceding tag is a perfect example. The tag name <fp11iso:datedImg> came from the following statement, which defines an ASP.NET user control:
<%@ Register TagPrefix="fp11iso" TagName="datedImg" Src="datedImg.ascx" %>
This is a directive that associates the tag prefix and name fp11iso:datedImg with the file datedImg.ascx. (The c in the third position of the file extension denotes control.) At a summary level, the datedImg.ascx file consists of these statements:
<%@ Control Language="vb" %> <script runat="server"> Public src1 As String = "" Public src2 As String = "" Public duration As String = "" Public start As String = "" Private Sub Page_Load(sender As Object, e As EventArgs) ' Program code goes here. End Sub </script> <img border="0" src="ballcyan.gif" id="imgPic" runat="server">
The @ Control directive sets options for a user control, just as the @ Page directive sets options for a complete page. The <script runat="server"> and </script> tags create a code declaration block as before. The four public variables src1, src2, duration, and start automatically receive the corresponding attribute values from the tag that loads the control.
The <img> tag on the last line is a template for the HTML that the control will create. It has a runat="server" attribute so that ASP.NET will load it as an object and an id= attribute so that code in the Page_Load subroutine can refer to it by name. Program code can read and modify the value of the src attribute by using the expression imgPic.src.
Here's the program code that goes inside the Page_Load subroutine:
Dim dteStart As Date ' Working copy of start date. Dim intDuration As Integer = 0 ' Working copy of duration. Dim strSource As String = "" ' Hold area for picture name. If IsDate(start) Then ' Is start date valid? dteStart = CDate(start) ' If so, convert to .NET Date. If IsNumeric(duration) Then ' If duration is valid intDuration = CInt(duration) ' Convert to .NET Integer, Else ' Otherwise intDuration = 14 ' Default to 14. End If ' Get difference between ' start date and today's date. Select Case DateDiff(DateInterval.Day, dteStart, Now.Date) Case < 0 ' If negative, use src1 strSource = src1 ' use src1, Case < intDuration ' If 0 through duration strSource = src2 ' use src2, Case Else ' Otherwise strSource = src1 ' use src1. End Select Else ' If start date is invalid strSource = src1 ' use src1. End If imgPic.Src = Request.ApplicationPath ' Initialize path. If Not imgPic.Src.EndsWith("/") Then ' If / is missing imgPic.Src &= "/" ' append it. End If imgPic.Src &= "images/" & strSource ' Append images folder ' and picture file name.
There are just two additional points worth mentioning:
- Dates in the .NET Framework are very large integers that count the number of 100-nanosecond ticks since midnight on January 1 of the year 1. This would make data arithmetic difficult, were it not for the availability of built-in functions like DateDiff. The DateDiff function returns the difference between two dates in any unit of measure you want.
- FrontPage doesn't automatically adjust the URLs in a custom server control as it does in ordinary HTML code. There's simply no way for FrontPage to figure out the difference between a URL and ordinary text. To provide some portability between pages in different locations, this control therefore builds an absolute path based on the current application root, plus the images folder, plus the picture file name. The expression Request.ApplicationPath returns the URL of the current application root.
Figure 42-6 shows how the sports.aspx page looks in a browser: perfectly normal. If you browse this page and choose Source from the View menu, you'll find ordinary <img> tags where <fp11iso:datedImg> tags appeared in the source file.
Because code for built-in ASP.NET controls like <asp:literal> and for custom controls like <fp11iso:datedImg> differs so markedly from the code that the Web visitor sees, you might wonder how FrontPage displays such controls. Figure 42-7 provides the answer: It displays them as gray boxes annotated with the type of control. This reflects the fact that the source code has no appearance until it runs and that each time it runs, the results might be different.
Figure 42-6. An ASP.NET custom control displays the ball, New!, or Upd! bullet pictures in this Web page based on attributes in the HTML and on the current date.
Figure 42-7. FrontPage displays ASP.NET controls as simple gray boxes.
Custom controls are one way that ASP.NET facilitates reuse of code. Once you have a custom control working, you can use it as often as you want in as many pages as you want, and never worry about duplicating code. If you do find a bug someday, fixing it in one place will fix it everywhere.
The sample files sports.aspx and datedImg.ascx contain both the HTML and the program code in one file. ASP.NET calls this the inline code model. When you create ASP.NET pages in Visual Studio .NET, the program code and the HTML reside in separate files. Visual Studio then compiles all the code files for a site into one DLL and adds directives to each Web page so that the page runs the correct code. This is the code-behind model, and it's also the technique that lets programmers and page designers work with separate files. The next chapter will discuss this technique in greater detail.
In Summary. . .
This chapter explained the fundamentals of using script code that runs on the Web server rather than on the browser and showed examples using both ASP and ASP.NET.
The next chapter will explain how to leverage the design and site management power of FrontPage and the programming power of Visual Studio .NET in one project.