Dot Net Perls

RewritePath Method Usage in ASP.NET

by Sam Allen - Updated June 13, 2009

Problem. You have page locations on your site that are easy to remember and convenient for users, but you want to redirect them to a central place in your code. This saves code footprint and encourages a friendly site design. Solution. Here we see how you can rewrite paths in ASP.NET using the RewritePath method.

Use RewritePath in ASP.NET to do internal redirects.
You can change a page name into a query string.
This allows a simpler design.
Events in Visual Studio

1. Using RewritePath

First, rewriting may be thought of as "internal" server-only redirecting. Global.asax is a useful file for your ASP.NET project and generally you should have one. It contains various event handlers for your project, and to add a new event handler, we simply type it in. ASP.NET will find it and use it on its own. Add an Application_BeginRequest event handler.

<%@ Application Language="C#" %>

<script runat="server">

    void Application_Start(object sender, EventArgs e)
    {
        // Code that runs on application startup
    }

    void Application_End(object sender, EventArgs e)
    {
        //  Code that runs on application shutdown
    }

    void Application_Error(object sender, EventArgs e)
    {
        // Code that runs when an unhandled error occurs
    }

    void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started
    }

    void Session_End(object sender, EventArgs e)
    {
        // Code that runs when a session ends.
        // Note: The Session_End event is raised...
        // is set to InProc in the Web.config file....
        // or SQLServer, the event is not raised.
    }

    void Application_BeginRequest(object sender, EventArgs e)
    {
        // You typed this
    }

</script>

Description of example. Global.asax shown. This is a special file in the root of your application's directory. It will be used and applied automatically when the site runs.

Auto-generated parts. The only part of the above file you must add is the Application_BeginRequest event. The rest will already be there. The standard signature for events has object and EventArgs arguments. It is important to include them even if you don't use them.

2. What does Application_BeginRequest do?

It receives each request that arrives at the ASP.NET application. It will receive requests for images, aspx files, and other files as people try to access those files on your server. Next we will use it to check for a certain kind of request, and then rewrite it.

3. Example problem

To rewrite paths, you need to know exactly what the request is for, and then what you must change it to. Here I will show some example required rewrites at my coding site. The purpose this rewriting accomplishes is that it allows all the code to be located in one file.

Path requested: /Content/ROT13.aspx
Rewritten path: default.aspx?file=rot13

Path requested: /Content/About.aspx
Rewritten path: default.aspx?file=about

Path requested: /Content/Array-Slice.aspx
Rewritten path: default.aspx?file=array-slice

4. Rewriting with strings

Here we see how you can add code to the Application_BeginRequest event handler that analyzes the HttpContent.Current path string. Detect if it needs to be rewritten, and if so, call RewritePath with the new path. The code that follows performs the rewriting in the table above.

void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext context = HttpContext.Current;
    string path = context.Request.Path.ToLower();

    int lastExtension = path.LastIndexOf(".aspx");
    if (lastExtension == -1)
    {
        return;
    }
    int lastContent = path.LastIndexOf("/content/");
    if (lastContent == -1)
    {
        return;
    }
    int lastSlash = path.LastIndexOf('/');
    string key = path.Substring(lastSlash + 1, (lastExtension - lastSlash - 1));

    context.RewritePath("~/default.aspx?file=" + key, false);
}

Notes on the example. The code above is run on each and every request that comes through ASP.NET. So, you will want to make it relatively fast. The first thing it does above is get the current HttpContext.

Using HttpContext.Current. It's a static property that returns the current "context" for the entire application. This means you can use the Request object anywhere, not just on a page file. [C# Singleton Pattern Versus Static Class - dotnetperls.com]

Rewriting logic. The code above references the request path. That's just a URL basically and we can treat it like any other string. Check my IndexOf article for information about the general idea here. These method calls return the positions of the substrings in the |path| string. We convert that to a query string, and pass in a virtual path to RewritePath.

5. Does this actually work?

Well, yes. If it didn't, you wouldn't be reading this article because you would be looking at a 404 error. This approach is a dynamic version of urlMappings. Use this sort of method for more complex requirements than urlMappings.

Task:     Rewrite very few paths
Solution: Use urlMappings and type them individually.

Task:     Rewrite many paths to query strings
          Hook friendly URLs to database
Solution: Use RewritePath method.
          Remember to check for validity.

Gotchas. One small problem my implementation of this had when I applied it was that I needed to specify the second argument "false" to RewritePath, which indicates whether to rebase client path. If you specify false, the page the client ends up on will be kept the same as the request would indicate.

6. Summary

Here we saw how you can rewrite paths in ASP.NET using the RewritePath method. Friendly URLs are valued more in search engine placement and are more likely to be bookmarked and shared than "ugly" or hard-to-read URLs. Utilize URL rewriting in ASP.NET in your Global.asax file for a dynamic and easily modifiable mechanism. You will want to change the string handling code and URLs here, but the general technique is effective.

Dot Net Perls
ASP.NET | ASHX Handler Tutorial | Cache Examples and Overview | Global Variables Example | Page_Load Event and AJAX | QueryString Usage
C# | Dictionary StringComparer Tip | DateTime.TryParse Example | Reflection Field Example | Validate Characters in String
© 2009 Sam Allen. All rights reserved.