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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With