This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.

MIND

New Directions in Redirection: Microsoft Internet Information Services 5.0 Provides Two New Methods for Redirection

Ram Papatla
This article assumes you're familiar with ASP and IIS 4.0
Level of Difficulty   1   2   3 
Code for this article: Papatla0400.exe (34KB)

SUMMARY Internet Information Services (IIS) 5.0 provides several enhancements to its support for ASP-based Web development, including two new server-side redirection methods: Server.Transfer and Server.Execute. Rather than redirecting requests with a round-trip to the client, these new methods can be used to transfer requests directly to an ASP file without ever leaving the server.
      While this functionality doesn't replace the Response.Redirect method used by IIS 4.0, you can take advantage of it to implement better application flow control mechanisms and to handle errors more efficiently. The different redirection options are described, along with some tips and tricks for implementing them on your own site.

T

he ASP programming language has become an industry standard for building Web applications. The ASP framework in Microsoft® Internet Information Services (IIS) 5.0 has undergone several important changes and enhancements, including two new ways to implement server-side redirection in ASP. These features are Server.Transfer, which transfers control to a new ASP script, and Server.Execute, which includes another ASP file's output in the current client-bound stream. These two methods join Response.Redirect, which has provided client-side redirection in previous versions of IIS. To better illustrate the workings of the new redirection methods, I will briefly discuss the server-side redirection mechanism present in IIS 4.0.

Redirection Mechanism in IIS 4.0

      If you've ever designed a Web site through more than one iteration, you've probably had to redirect your users one or more times before they reached their final destination. Depending on the speed of the user's connection, their experience could range from seamless (no latency at all) to annoyingly noticeable. In the ASP environment, a redirection (also known as a 302 message) is achieved using the Response.Redirect method. When Response.Redirect is used, anything you've explicitly written to the response body using Response.Write is ignored. Other HTTP headers that are set in the page (for example, with Response.AddHeader) are kept. The Response.Redirect method sends the following HTTP header:

HTTP 1.0 302 Object Moved
Location URL

Here, URL represents the value passed to the method. In your ASP code, the following line will issue a redirection to https://www.microsoft.com:


<% Response.Redirect "https://www.microsoft.com" %>

      What's actually happening here? After the server processes the initial request, the ASP code issues a redirection to a different page, making the browser automatically request a new page. If you need to send any content to the browser before the redirection, you must turn on buffering on the server with Response.Buffer as the first line of the script. Figure 1 shows an example of file1.asp using Response.Redirect with buffering turned on.

Figure 2 Response Redirect
Figure 2Response Redirect

       Figure 2 shows the Response.Redirect process. The client sends a request to file1.asp, which in turn contains code that redirects the user to file2.asp. The code in file1.asp is executed. The client then requests file2.asp, and the browser returns the message "Redirection Complete." An example of the Response.Write portion of file2.asp is shown in Figure 3.
      What are the ramifications of this method? Since the redirection goes through a round-trip to the browser, it generates an additional request and increased bandwidth usage. More importantly, useful state information is lost in the process.
      Buffering is turned off by default in IIS 4.0; if you upgrade to Windows 2000, buffering will remain off. However, on a clean install of Windows 2000 with IIS 5.0, buffering is turned on by default. In the example I just showed, leaving buffering off would have generated this ASP error:


Response object error 'ASP 0156 : 80004005'. 

This occurs when the client is redirected after the server writes some content to the browser, as was the case here.

New Redirection Mechanism in IIS 5.0

      Internet Information Services 5.0 represents a new Internet architecture that's in place for Windows 2000. Rather than redirecting requests with a round-trip to the client, the two new methodsâ€"Server.Transfer and Server.Execute â€"can be used to transfer requests directly to an ASP file without ever leaving the server. Buffering does not have to be turned on for this feature to work. However, if buffering is turned on, the ASP file that's the target of the redirection can modify HTTP headers. If buffering is off, the redirection target can only modify the HTTP headers if the referring page has sent no content. If you are upgrading from IIS 4.0 and leave buffering off by default, the new redirect methods will work just fine.
      It is recommended that the buffering be left on in IIS 5.0, since it decreases network and CPU utilization by batching the data to be sent instead of performing multiple writes. However, when buffering is on, the user has to wait for the entire page to be executed before seeing any results. You can provide a better user experience by judiciously placing a Response.Flush call or two in your code to send the page in two or more chunks.

Server.Transfer

      The Server.Transfer method simply sends requests from one executing ASP file to another file (see Figure 4).

Figure 4 Server.Transfer
Figure 4Server.Transfer

As a result of the transfer, the original ASP file terminates execution. The requested information is then made available to the destination file when it begins execution. But that's not the coolest part. When you use Server.Transfer, the destination ASP script has access to the same set of intrinsic objects (Request, Response, Server, Session, and Application) as the originally requested file. You don't have to rebuild this information before you redirect to the new URL.
       Figure 5 shows an example of file1.asp, this time using Server.Transfer for the redirection. You'll see that the script in file1.asp was processed until the Server.Transfer method was called. It did not write the string foo, since it was terminated and file2.asp was executed. Figure 6 shows the session increment portion of file2.asp. However, the session value is preserved after the transfer and was incremented to 2. At this point the browser has not changed the URL. The browser returns:


  The count = 2

Server.Execute

      The other method, Server.Execute, is shown in Figure 7. This method is analogous to a procedure call in VBScript, except that instead of executing a procedure, an ASP file is being executed. Server.Execute sends requests from one executing ASP file to another file, completes the execution of the requested ASP file (like file2.asp in Figure 5), and then returns to continue the execution of the primary ASP file. Just like with the Server.Transfer method, the destination file has access to the same set of intrinsic objects as the originally requested file, and the URL in the browser remains the same.

Figure 7 Server.Execute
Figure 7Server.Execute

      The ASP file file1.asp is processed until the Server.Execute method is called. The script then executes the code in file2.asp and sends the session value to the client. When it's finished processing file2.asp, it returns to file1.asp and continues where it left off, writing the string foo to the browser. The browser returns:


The count = 2
foo

More Advantages

      When you use the Server.Transfer and Server.Execute methods, the ASP intrinsic objects are transferred and maintained. In addition, these methods support the transaction flags. In IIS 4.0, you were introduced to three transaction flags: Required, Requires New, and Not Supported. This behavior has not changed in IIS 5.0. However, if an ASP file executes a transacted ASP file using the new Server.Execute or Server.Transfer methods, the transaction flag state is maintained for the second ASP file. If the second ASP file's transaction flags indicate that transactions are supported or required, then the existing transaction will be used and a new transaction will not be started.
      Server.Transfer is also useful in error handling procedures. In IIS 5.0, the ASPError object is called when an error is generated. The Server.GetLastError method returns an ASPError object describing the error condition that occurred. If this method is called after an automatic Server.Transfer, it will provide information about what caused the error. There are a couple of advantages in this scenario. An ASP developer can troubleshoot the error with the data from the ASPError object. In some cases, the error can be fixed without the user knowing that an error has occurred.
      This brings up another question. How many times can you use these methods? The answer is that Server.Transfer and Server.Execute can be called an unlimited number of times. Since there's no enforced limit, you should be extra careful not to accidentally create any infinite loops, since two scripts call each other.

Ramifications of These Methods

      I know that some developers feel that these two new methods will replace Response.Redirect, but that is not the intent. These methods are primarily designed to work on a single machine only. One drawback of using Server.Transfer or Server.Execute is that it is not possible to use these methods to redirect to another machine or domain. Attempting that will generate an ASP error.
      The next caveat I should mention is that these new redirection calls don't change the current URL itself. Therefore, you must be careful when using relative URLs within Web pages. For example, let's assume that file2.asp is in the Web server's root directory, while file1.asp resides in a virtual directory under the root. When you use the Server.Transfer method to transfer from file1.asp to file2.asp, you must make sure that all the relative links in file2.asp are relative to the location of file1.asp for them to work properly. Since using relative URLs can pose serious problems, the workaround is to use absolute addresses in all your URLs.
      Another behavior that can cause problems is that when either of these methods is used, the entire content of the transferred or executed file will be compiled and sent back to the browser. Let's review the example used for Server.Execute. The browser returned:


The count = 2
foo

When you examine the HTML code that's returned to the browser (see Figure 8), notice that it has multiple <HTML> and <BODY> tags, which could be a problem. Although most browsers can display the page properly anyway, it's bad HTML code. This behavior is similar to using the include file method. Just as you would use include files with caution (by eliminating <HTML> and <BODY> tags), when using Server.Transfer and Server.Execute you must also do this.
      Yet another reason these new methods won't replace Response.Redirect is that you cannot redirect using a query string; you have to use Response.Redirect.
      While it's quite handy that session and application scope is carried over to the transferred or executed file, what about the global.asa file? The answer is that since Server.Execute and Server.Transfer both retain a session's state, ASP doesn't start a new application or call a new global.asa for the executed or transferred ASP file. If you are running /foo/file1.asp and it calls Server.Execute("/bar/file2.asp") or Server.Transfer("/bar/file2.asp"), the bar application's global.asa is not activated, and session or application events do not run.

A Final Word

      Server.Transfer and Server.Execute create a better application flow control mechanism for the ASP framework. Server.Transfer also facilitates efficient handling of errors. While they won't replace Response.Redirect for all your redirection needs, these new methods are two improvements that will help you build robust, scalable, reusable Web applications that run on IIS 5.0.

Ram Papatla is an engineer with the Internet Information Services (IIS) group at Microsoft, dealing with migrating real-world customer applications to the Microsoft Windows DNA architecture on Windows 2000 with IIS 5.0. Reach him at rpapatla@microsoft.com.

From the April 2000 issue of MSDN Magazine.