Q:

Accessing original URL in IIS7 404 redirect page

I have an .aspx page as my custom 404 page on a site set up on IIS 7.   I need to retrieve the original URL that the user was trying to access in order to do some processing on the 404 page.   The trick is that I need to specifically handle 404's that do not contain a .aspx extension (e.g http://example.com/testurl), which do not get routed through ASP.NET's custom errors section.   I can configure IIS to point to my custom 404, but at that point I do not know how to get my original URL?   Does anyone know if this is possible? 
Thanks,
Mike

A:

Yes, it is possible to get the URL that causes the 404 error, you just need to make sure you have IIS configured properly. 
There are two cases you need to handle, one is where the error comes from an .aspx or other page that is handled by .NET, and the other is where the error comes from a bad folder (as in your question, http://example.com/testurl) or filename (for example, *.htm) that is not handled by .NET.   In IIS 7, you'll need to configure a custom 404 error under ".NET Error Pages" in the "ASP.NET" section for your web app, and also under "Error Pages" in the "IIS" section.   The web.config changes end up looking something like this:
<system.web>
    <!--  other system.web stuff -->
    <customErrors defaultRedirect="/Error404.aspx" mode="On" redirectMode="ResponseRewrite">
        <error redirect="/Error404.aspx" statusCode="404" />
    </customErrors>
</system.web>
<system.webServer>
    <!--  other system.webServer stuff -->
    <httpErrors errorMode="Custom">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" prefixLanguageFilePath="" path="/Error404.aspx" responseMode="ExecuteURL" />
    </httpErrors>
</system.webServer>

Note: the redirectMode="ResponseRewrite" listed above is important if you want your 404 pages to actually return 404 messages and I don't think it can be set through IIS. 
In my example, I created a page called Error404.aspx to handle all of the 404 errors.   When a .NET page (.aspx, etc) throws a 404 exception, the original filename can be found in the aspxerrorpath querystring variable.   When a regular htm or other page causes a 404 error, the original path can be read from the Request. RawUrl property.   I used the following code in my Error404.aspx page to handle either case:
public partial class Error404 : System. Web. UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        OriginalUrl = Request. QueryString["aspxerrorpath"] ??  Request. RawUrl;
        Server. ClearError();
        Response. Status = "404 not found";
        Response. StatusCode = 404;
    }

    public string OriginalUrl { get; private set; }
}

By default, the 404 error page will not return a 404 status code, so you need to set it manually.   See this post for more detail.