Once and for all what is the best routing approach to handle errors, exceptions and 404's in MVC
There are many articles on SO and the web in attempts to handle 404's and exceptions gracefully.
From what I have read the best advice seems 开发者_开发知识库to be have a route for 404's like so:
routes.MapRoute(
"404-PageNotFound",
"{*url}",
new { controller = "ErrorController", action = "PageNotFound" }
);
Then for other errors have the HandleError
atribute on the Controller and have CustomErrors turned on in web.config so it goes to the error.cshtml page.
However I have read that if you get a exception that does not set the HTTP code to 500 the HandleError will not work.
Can we finally produce an answer/best practice that handles 404's/Exceptions/ASP.Net errors where we can apply to this to all our projects?
Thanks
I use a simple error handling setup. Nice and simple. More info can be found at http://erictopia.com/2010/04/building-a-mvc2-template-part-7-custom-web-errors-and-adding-support-for-elmah/
Install ELMAH and have it handle all the errors.
Next create an Error controller. Add a catch all route like this:
routes.MapRoute(
"ErrorHandler", // Route name
"{*path}", // URL
new { controller = "Error", action = "Index" }
);
Then in web.config add this section:
<customErrors mode="RemoteOnly" defaultRedirect="/Error/Index">
<error statusCode="403" redirect="/Error/NoAccess" />
<error statusCode="404" redirect="/Error/NotFound" />
</customErrors>
No need to set up a 404 route. In global asax application start, set up a global filter to catch 404 where the controller exists but not the action, or if an action returns a 404 result.
filters.Add(new HttpNotFoundFilterAttribute { Order = 99 });
where the filter is an ActionFilterAttribute with this override:
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result !=null &&
(filterContext.Result.GetType() == typeof(HttpNotFoundResult) )
{
//You can transfer to a known route for example
filterContext.Result = new TransferResult(SomeAction, SomeController);
}
}
And also in Application_Error, in case no controller exists:
Exception ex = Server.GetLastError();
string uri = null;
if (Context != null && Context.Request != null)
{
uri = Context.Request.Url.AbsoluteUri;
}
Exception baseEx = ex.GetBaseException();
var httpEx = ex as HttpException;
if ((httpEx != null && httpEx.GetHttpCode()==404)
|| (uri != null && Context.Response.StatusCode == 404) )
{ /* do what you want. */
//Example: show some known url
Server.ClearError();
Server.TransferRequest(transferUrl);
}
To avoid handling 404 for static resources, you should install SP1 on Windows 7 or windows 2008 R2 to upgrade IIS7 and set in web.config:
...
<modules runAllManagedModulesForAllRequests="false">
...
精彩评论