Click here to Skip to main content
15,892,643 members
Articles / Web Development / IIS

URL Rewriting using ASP.NET for SEO

Rate me:
Please Sign up or sign in to vote.
4.73/5 (25 votes)
25 Feb 2009CPOL15 min read 165.1K   6.8K   130  
An article describing how to implement URL rewriting in ASP.NET using three different methods
using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Web.UI;
using System.Web.SessionState;

public class BetterUrlRewriter : IHttpHandler, IRequiresSessionState
{    
    const string ORIGINAL_PATHINFO = "UrlRewriterOriginalPathInfo";    
    const string ORIGINAL_QUERIES = "UrlRewriterOriginalQueries";     
    
    public void ProcessRequest(HttpContext context)    
    {        
        // Check to see if the specified HTML file actual exists and serve it if so..        
        String strReqPath = context.Server.MapPath(context.Request.AppRelativeCurrentExecutionFilePath);        
        if (File.Exists(strReqPath))        
        {            
            context.Response.WriteFile(strReqPath);            
            context.Response.End();            
            return;        
        }         
        
        // Record the original request PathInfo and QueryString information to handle graceful postbacks        
        context.Items[ORIGINAL_PATHINFO] = context.Request.PathInfo;        
        context.Items[ORIGINAL_QUERIES] = context.Request.QueryString.ToString();         
        
        // Map the friendly URL to the back-end one..        
        String strVirtualPath = "";        
        String strQueryString = "";        
        MapFriendlyUrl(context, out strVirtualPath, out strQueryString);         
        if(strVirtualPath.Length>0)        
        {
            foreach (string strOriginalQuery in context.Request.QueryString.Keys)
            {
                // To ensure that any query strings passed in the original request are preserved, we append these                 
                // to the new query string now, taking care not to add any keys which have been rewritten during the handler..                
                if (strQueryString.ToLower().IndexOf(strOriginalQuery.ToLower() + "=") < 0)                
                {                    
                    strQueryString += string.Format("{0}{1}={2}", ((strQueryString.Length > 0) ? "&" : ""), strOriginalQuery, context.Request.QueryString[strOriginalQuery]);                
                }            
            }             
            
            // Apply the required query strings to the request            
            context.RewritePath(context.Request.Path, string.Empty, strQueryString);             
            // Now get a page handler for the ASPX page required, using this context.              
            Page aspxHandler = (Page)PageParser.GetCompiledPageInstance(strVirtualPath, context.Server.MapPath(strVirtualPath), context);             
            // Execute the handler..            
            aspxHandler.PreRenderComplete += new EventHandler(AspxPage_PreRenderComplete);            
            aspxHandler.ProcessRequest(context);        
        }        
        else        
        {            
            // No mapping was found - emit a 404 response.             
            context.Response.StatusCode = 404;            
            context.Response.ContentType = "text/plain";            
            context.Response.Write("Page Not Found");            
            context.Response.End();        
        }    
    }     
    
    void MapFriendlyUrl(HttpContext context, out String strVirtualPath, out String strQueryString)    
    {        
        strVirtualPath = ""; strQueryString = "";     
            
        // TODO: This routine should examine the context.Request properties and implement        
        //       an appropriate mapping system.        
        //        
        //       Set strVirtualPath to the virtual path of the target aspx page.        
        //       Set strQueryString to any query strings required for the page.         
        
        if (context.Request.Path.IndexOf("FriendlyPage.html") >= 0)        
        {            
            // Example hard coded mapping of "FriendlyPage.html" to "UnfriendlyPage.aspx"             
            
            strVirtualPath = "~/UnfriendlyPage.aspx";            
            strQueryString = "FirstQuery=1&SecondQuery=2";        
        }    
    }     
    
    void AspxPage_PreRenderComplete(object sender, EventArgs e)    
    {        
        // We need to rewrite the path replacing the original tail and query strings..        
        // This happens AFTER the page has been loaded and setup but has the effect of ensuring        
        // postbacks to the page retain the original un-rewritten pages URL and queries.         
        
        HttpContext.Current.RewritePath(HttpContext.Current.Request.Path,                                        
        HttpContext.Current.Items[ORIGINAL_PATHINFO].ToString(),                                        
        HttpContext.Current.Items[ORIGINAL_QUERIES].ToString());    
    }     
    
    public bool IsReusable    
    {        
        get        
        {            
            return true;        
        }    
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Hidalgo Limited
United Kingdom United Kingdom
Steve is an MCP and senior software developer for Hidalgo Limited (http://www.hidalgo.co.uk).

Comments and Discussions