Question

I recently migrated a website to a new CMS (Umbraco). A lot of the links have changed, but they can be easily corrected by searching for patters in the url, so I would like to write something that will redirect to the correct page if the old one is not found. That part isn't a problem.

How can I obtain the requested URL after the browser is redirected to my custom 404 page. I tried using:

request.ServerVariables("HTTP_REFERER") 'sorry i corrected the typo from system to server.

But that didn't work.

Any Ideas?

The site is on IIS 6.0. We did consider using 301 redirects, but we don't have any way of knowing what pages people have bookmarked and there are a few hundred pages, so no one is keen on spending the time to create the 301's.

Was it helpful?

Solution

I do basically the same thing you ask in a custom 404 error handling page. On IIS 6 the original URL is in the query string. The code below shows how to grab the original URL and then forward the user. In my case I switched from old ASP to new ASP.NET, so all the .asp pages had to be forwarded to .aspx pages. Also, some URLs changed so I look for keywords in the old URL and forward.

//did the error go to a .ASP page?  If so, append x (for .aspx) and 
//issue a 301 permanently moved
//when we get an error, the querystring will be "404;<complete original URL>"
string targetPage = Request.RawUrl.Substring(Request.FilePath.Length);

if((null == targetPage) || (targetPage.Length == 0))
    targetPage = "[home page]";
else
{
     //find the original URL
    if(targetPage[0] == '?')
    {
        if(-1 != targetPage.IndexOf("?aspxerrorpath="))
             targetPage = targetPage.Substring(15); // ?aspxerrorpath=
        else
             targetPage = targetPage.Substring(5); // ?404;
        }
        else
        {
             if(-1 != targetPage.IndexOf("errorpath="))
             targetPage = targetPage.Substring(14); // aspxerrorpath=
             else
            targetPage = targetPage.Substring(4); // 404;
        }
    }               

    string upperTarget = targetPage.ToUpper();
    if((-1 == upperTarget.IndexOf(".ASPX")) && (-1 != upperTarget.IndexOf(".ASP")))
    {
        //this is a request for an .ASP page - permanently redirect to .aspx
        targetPage = upperTarget.Replace(".ASP", ".ASPX");
        //issue 301 redirect
        Response.Status = "301 Moved Permanently"; 
        Response.AddHeader("Location",targetPage);
        Response.End();
    }

    if(-1 != upperTarget.IndexOf("ORDER"))
    {
                //going to old order page -- forward to new page
               Response.Redirect(WebRoot + "/order.aspx");
           Response.End();
    }

OTHER TIPS

How about:

Request.ServerVariables("HTTP_REFERER");

A lot of the links have changed, but they can be easily corrected by searching for patters in the url

Rather than send your users to a 404, have you considered using url re-writes? This way your users (and search engines, if that's important to you in this case) will get a 301 or 302 rather than having to go through your 404 handler. It's usually quicker and less stressful on your servers to handle the rewrite at the url level than firing up your code and processing it there.

Microsoft have released a URL Rewrite Module for IIS 7, and there's a decent introduction to it here and here.

For IIS 6, there's a good intro here to getting URL rewriting working with it, slightly different than IIS7.

An example rewrite rule would be

# $1 will contain the contents of (.*) - everything after new-dir/
RewriteRule /new-dir/(.*) /find_old_page.asp?code=$1 

there are a few hundred pages, so no one is keen on spending the time to create the 301's

The beauty of rewrite rules is that you don't need to list to explicitly list all of your pages, but can write rules which follow the same pattern. We had to do something similar to this recently, and it's surprising how many of the moved urls could be handled by a couple of simple rules.

Instead of using a 404 page, I think the proper thing to do would be to redirect with a 301 - Moved Permanently code.

Here's what we do on init on our 404 pages:

Dim AttemptedUrl As String = Request.QueryString("aspxerrorpath")
If Len(AttemptedUrl) = 0 Then AttemptedUrl = Request.Url.Query
AttemptedUrl = LCase(AttemptedUrl)
CheckForRedirects(AttemptedUrl)

CheckforRedirects then has custom logic to match up old URLs with new URLs.

I'd argue that this is the preferred approach (as opposed to 301s or URL rewriting) if you have enough information internally to match up a large number of URLs from the old system with the new system - e.g. if you have a table that matches up old IDs with new IDs or something similar.

If there's a consistent pattern that you can use to map old URLs to new URLs with a regex, though, then URL rewriting would be the way to go.

To build on the Rewrites suggestion, Umbraco already uses UrlRewriting.NET and new rewrites can be added to

\config\UrlRewriting.config

Hope this helps

Update, you actually want to pick up:

VB.NET:

Request.QueryString("aspxerrorpath")

C#:

Request.QueryString["aspxerrorpath"];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top