Question

I'm creating a Controller and View for "Gone" requests (410 code) and the way I've done this is adding the customError status code 410 to my Web.config.

This properly handles the exception and renders the view, but the response URL is

http://www.mysite.com/Error/Gone?aspxerrorpath=/requested-page

I'd wish to preserve the original URL while still showing the Gone View, in other words, leave the url as is: "http://www.mysite.com/requested-page"

Any idea where I could start this?

Was it helpful?

Solution

To preserve the original URL you could go the route described here and handle errors explicitely inside global.asax instead of using web.config customerrors or httperrors sections (which can still be configured for fallback) but change the IHttpHandler.ProcessRequest part on linked websites example with HttpContext.Server.TransferRequest(path, true). I've implemented the Application_Error event like this in one of my projects:

protected void Application_Error()
{
    Exception error = Server.GetLastError();
    var code = (error is HttpException) ? (error as HttpException).GetHttpCode() : 500;

    if (!Context.IsDebuggingEnabled
        && code != 404)
    {
        // persist error to error log db
        //Log.Logger.Error("unhandled exception: ", exception);
    }

    if (WebConfigurationManager.AppSettings["EnableCustomExceptionPage"].Equals("false"))
    {
        return;
    }

    Response.Clear();
    Server.ClearError();

    string path = this.Request.Path;
    string action;
    switch (code)
    {
        case 401:
            action = "Unauthorized";
            break;
        case 403:
            action = "Forbidden";
            break;
        case 404:
            action = "NotFound";
            break;
        default:
            action = "Generic";
            break;
    }
    string newPath = string.Format("~/Error/{0}?source={1}&message={2}", action, path,
                                   HttpUtility.UrlEncode(error.Message));
    Context.Server.TransferRequest(newPath, true);
}

Internally it transfers the request to a new path handled i.e. by an ErrorController like in the described example above which actions could look like this:

public ViewResult Generic(string source, string message)
{
    Response.TrySkipIisCustomErrors = true;
    Response.StatusCode = 500;
    ViewBag.Source = source;
    ViewBag.Message = HttpUtility.UrlDecode(message);
    return View();
}

public ViewResult NotFound(string source, string message)
{
    Response.TrySkipIisCustomErrors = true;
    Response.StatusCode = 404;
    ViewBag.Source = source;
    ViewBag.Message = HttpUtility.UrlDecode(message);
    return View();
}

...

The TrySkipIisCustomErrors = true prevents IIS from redirecting to the default custom error pages. You can handle thrown Exceptions (like special Exceptions thrown in business/service layer) other than HttpException differently inside Application_Error override method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top