可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
回答1:
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>
回答2:
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"> ...