Hot Tip
LANGUAGE: C#
ASP.NET VERSIONS: 1.0 | 1.1
Rewrite URLs on the Fly
Use HttpContext.RewritePath to "fake" URLs
within an application.
By Jeff Prosise
One of the more obscure - but potentially useful - methods
in the portion of the .NET Framework that comprises ASP.NET is the HttpContext
class's RewritePath method. Used internally by ASP.NET to strip session IDs
from URLs when cookieless session state is enabled, RewritePath can also be
used to "fake" URLs within an application. To demonstrate, consider the
following ASPX file, which we'll call RewritePath.aspx:
<html>
<body>
<h2><asp:Label ID="Output" RunAt="server"
/></h2>
</body>
</html>
<script language="C#" runat="server">
void Page_Load (Object sender, EventArgs e)
{
string id = Request.QueryString["ID"];
if (id != null
&& id != String.Empty) {
switch (id) {
case
"1":
Output.Text =
"Give me chastity and " +
"continence, but not yet.";
break;
case
"2":
Output.Text =
"A programmer is a device " +
"for
turning coffee into code.";
break;
case
"3":
Output.Text =
"Blessed is the man who, " +
"having nothing to say, abstains from " +
"giving wordy evidence of the
fact.";
break;
}
}
}
</script>
If this page is deployed in a virtual directory named Foo,
then the following URLs invoke the page and display three different quotations:
http://.../foo/rewritepath.aspx?id=1
http://.../foo/rewritepath.aspx?id=2
http://.../foo/rewritepath.aspx?id=3
So far, so good. Now suppose that you'd like users to be
able to display these quotations by typing the following "phantom" URLs:
http://.../foo/quotes/page1.aspx
http://.../foo/quotes/page2.aspx
http://.../foo/quotes/page3.aspx
You can accomplish this little bit of magic - converting a
URL of the form .../quotes/page1.aspx into a URL of the form
.../rewritepath.aspx?id=1 on the fly - with HttpContext.RewritePath. The trick
is to grab each request for /quotes/page1.aspx, /quotes/page2.aspx, and so on
as it enters ASP.NET's HTTP pipeline and convert it into a request for
/rewritepath.aspx?id=1, /rewritepath.aspx?id=2, and so on. Here's a Global.asax
file that does just that:
<script language=C# runat="server">
void Application_BeginRequest (Object sender, EventArgs e)
{
//
// TODO: Convert a
path of the form
//
.../quotes/page1.aspx into a path of the form
//
.../rewritepath.aspx?id=1
//
HttpContext context =
HttpContext.Current;
string oldpath =
context.Request.Path.ToLower ();
string token =
"/quotes/page";
int i =
oldpath.IndexOf (token);
int len =
token.Length;
if (i != -1) {
int j =
oldpath.IndexOf (".aspx");
if (j != -1) {
string id =
oldpath.Substring (i + len, j - (i + len));
string newpath
=
oldpath.Replace (token + id + ".aspx",
"/rewritepath.aspx?id=" + id);
context.RewritePath
(newpath);
}
}
}
</script>
Application_BeginRequest fires at the beginning of every
request. This implementation extracts the path portion of the URL targeted by
the request (for example, /foo/quotes/page1.aspx), replaces it with a path that
refers to the real page (for example, /foo/rewrite.aspx?id=1), and calls
RewritePath to retarget the request. Try it: Drop RewritePath.aspx into wwwroot
on your Web server and try to invoke it by typing this URL into your browser's
address bar:
http://localhost/quotes/page1.aspx
That should generate a "page not found" error. Now copy
Global.asax to wwwroot and try again. This time, it should work just fine,
thanks to the indirection afforded by Application_BeginRequest.
RewritePath has many applications. You can use it, for
example, to convert query strings into path names so pages that use query
string parameters to drive content can be bookmarked in browsers. You can also
use it to obfuscate path names within your application for security reasons.
Now that you know RewritePath exists, you may find other uses for it, too.
Jeff Prosise is
author of several books, including Programming Microsoft .NET (Microsoft Press). He also is a
co-founder of Wintellect (http://www.wintellect.com), a
software consulting and education firm that specializes in .NET. Contact Jeff
at mailto:askthepro@aspnetPRO.com.