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.
MVC has a built in support to handle Exceptions and display a custom view. By default MVC adds
HandleErrorAttributeto theRegisterGlobalFiltersmethod in theGlobal.asax.csfile.You need to add a view Named
Errorto theSharedview folder. The view will have a model of typeHandleErrorInfowhich as a property namedExceptionto get the thrown exception