Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Exception to Custom Error Page using IIS7 httpErrors

I've created an ASP.NET MVC 3 application, using httpErrors to handle the displaying of error messages and the like to the user. That code works fine, and is duplicated below.

<httpErrors existingResponse="Replace" defaultResponseMode="ExecuteURL" errorMode="Custom">
  <clear/>
  <error statusCode="403" path="/Error/Forbidden" responseMode="ExecuteURL"/>
  <error statusCode="404" subStatusCode="-1" path="/Error/NotFound" responseMode="ExecuteURL"/>
  <error statusCode="500" subStatusCode="-1" path="/Error/ServerError" responseMode="ExecuteURL"/>
</httpErrors>

When an exception in a controller occurs, BaseController.OnException is triggered (BaseController is a class of my own creation). What I want to do in that function is store the exception so that my ServerError action can look at its type and message to determine what to display to the user. The entire method is copied below.

protected override void OnException(ExceptionContext filterContext)
{
    // doesn't work
    this.TempData["exception"] = filterContext.Exception;

    // doesn't work
    this.Session["exception"] = filterContext.Exception;

    // temporary hack
    ErrorController.RequestExceptions[this.Request.UserHostAddress] = filterContext.Exception;
    base.OnException(filterContext);
}

When the request arrives at the ErrorController instance (ErrorController is in a different namespace, but I don't think that's relevant), for some reason Server.GetLastError() returns null, TempData is empty, Session is empty, and Session.IsNewSession is true. I tried to work around the problem by having the app store some sort of request ID, but that doesn't appear to exist, and right now the best solution I've got is this extremely hacky "store it by requesting IP, then remove it as soon as the ErrorController has picked it up."

This (amazingly) works, but there has to be a safer and more scalable solution. I'm not sure why TempData is cleared or why Session is restarted - is it because of the error, or does this count as two separate requests? Regardless, is there a workaround to get the desired behavior?

P.S. I would prefer, if possible, to use the httpErrors entry in web.config rather than code in Application_Error: It seems like a cleaner, more declarative solution.

P.P.S. I found an article about problems with the Session object during redirects (link) but it says the problem has been fixed. Most of the other things I've come across have been about the older customErrors system, but I'm going to keep looking.

like image 485
ehdv Avatar asked Dec 15 '11 04:12

ehdv


People also ask

How do you display a custom error page with error code using httpErrors in asp net?

Add the following <httpErrors> section under <system. webServer> section, as shown below. The above <httpErrors> replaces the response coming from ASP.NET with the matching status code and return a custom HTML file as a response. This will preserve the URL and return a custom error page with an appropriate error code.

How do I redirect an error page in web config?

The <customErrors> section in Web. config has two attributes that affect what error page is shown: defaultRedirect and mode . The defaultRedirect attribute is optional. If provided, it specifies the URL of the custom error page and indicates that the custom error page should be shown instead of the Runtime Error YSOD.


1 Answers

MVC has a built in support to handle Exceptions and display a custom view. By default MVC adds HandleErrorAttribute to the RegisterGlobalFilters method in the Global.asax.cs file.

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

You need to add a view Named Error to the Shared view folder. The view will have a model of type HandleErrorInfo which as a property named Exception to get the thrown exception

@model System.Web.Mvc.HandleErrorInfo

@Model.Exception.Message
like image 155
Eranga Avatar answered Nov 03 '22 01:11

Eranga