A common way to build the navigation and layout for an ASP-driven website is to use include files. Most advanced ASP developers know that when you do this, it is best to encapsulate the functionality of the include file in a Sub or Function, and then to call this routine from the page that is including the file. This avoids problems with variable scope, allows parameters to be passed easily to the include file, and makes the code easier to read.
As these sites are migrated to use ASP.NET, it is likely that classic ASP and ASP.NET pages will exist side-by-side, which is one of the touted advantages of ASP.NET. Unfortunately, there is no built-in way for an ASP.NET page to take advantage of a classic ASP include file, which means that the obvious solution if you want to maintain a consistent look and feel is to duplicate the look of the classic ASP template in an ASP.NET user control. Unfortunately, this means duplicating presentation logic, and inevitably, the classic ASP template and the ASP.NET template will get out of sync.
To overcome this problem, I built a simple user control that uses ASP.NET's built-in page-scraping library, HTTPWebResponse, to grab a template ASP file and render it in my .aspx page. The template ASP file is simply a page that includes my presentation logic include file, and calls the functions to render the HTML, passing through any querystring parameters it has to those functions (such as for page title for a header include file).
For this demonstration, there are six files:
layout_sample.asp - this ASP page uses the include file the standard Classic ASP way.
header_include.asp - this is my actual ASP include file, which has a function called showHeader that will display the HTML for the page header wherever it is called. The page header is just an HTML table with the title of the page in it. The title is passed into showHeader as a required parameter.
header_template.asp - this is my template file. All it does is include my ASP header include file, call the showHeader function, and insert the querystring parameter for the title. If you click on this page, add "?title=foo" to the url to see how it uses the title from the querystring.
showHeader.ascx -- My user control that scrapes an ASP page to get the HTML to insert in my .aspx page.
showHeader.ascx.cs -- The code-behind file for my user control.
layout_sample.aspx - this ASP.NET page will use the Classic ASP layout
The Classic ASP example is very simple. All it does is include a file, call showHeader, and wrap it all in a basic HTML page:
1 <%Option Explicit%>
2 <!-- #INCLUDE FILE="header_include.asp" -->
3 <%
4 'Declare Variables
5 Dim title
6
7 title = "Sample Layout"
8 %>
9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
10 "http://www.w3.org/TR/REC-html40/loose.dtd">
11 <html>
12 <head>
13 <title><%=title%></title>
14 </head>
15 <body>
16 <% Call showHeader(title) %>
17 <p>
18 This is the main content of my sample Classic ASP page. Compare it to the
19 <a href="layout_sample.aspx">ASP.NET version</a>.
20 </p>
21 </body>
22 </html>
The include file is equally simple -- a single method that outputs some HTML. Note that this file can be called by either VBScript or JScript ASP pages, and avoids any context switching. It could also be called several times on one page, if need be.
1 <script runat="server" language="vbscript">
2 Sub showHeader(title)
3 Response.Write "<table width=""100%"" bgcolor=""#CC0000"" border=""1"">"
4 Response.Write "<tr><td align=""center""><b>" & title & "</b></tr></td>"
5 Response.Write "</table>"
6 End Sub
7 </script>
Now let's take a look at the real "hack" pa