一劳永逸是什么是处理MVC中的错误,异常和404的最佳路由方法

时间:2011-06-05 09:21:56

标签: c# asp.net asp.net-mvc asp.net-mvc-3

有很多关于SO和网络的文章试图优雅地处理404和异常。

根据我的阅读,最好的建议似乎是404这样的路线:

routes.MapRoute(
    "404-PageNotFound",
    "{*url}",
    new { controller = "ErrorController", action = "PageNotFound" }
    );

然后,对于其他错误,在Controller上有HandleError属性,并在web.config中打开CustomErrors,因此它会转到error.cshtml页面。

但是我已经读过,如果你得到一个没有将HTTP代码设置为500的异常,那么HandleError将无效。

我们能否最终制定一个处理404 / Exceptions / ASP.Net错误的答案/最佳实践,我们可以将其应用于我们的所有项目?

由于

2 个答案:

答案 0 :(得分:1)

我使用简单的错误处理设置。很好,很简单。更多信息可以在http://erictopia.com/2010/04/building-a-mvc2-template-part-7-custom-web-errors-and-adding-support-for-elmah/

找到

安装ELMAH并让它处理所有错误。

接下来创建一个错误控制器。像这样添加所有路线:

routes.MapRoute(
    "ErrorHandler", // Route name
    "{*path}",      // URL
    new { controller = "Error", action = "Index" }
);

然后在web.config中添加此部分:

<customErrors mode="RemoteOnly" defaultRedirect="/Error/Index">
        <error statusCode="403" redirect="/Error/NoAccess" />
        <error statusCode="404" redirect="/Error/NotFound" />
</customErrors>

答案 1 :(得分:0)

无需设置404路线。 在全局asax应用程序启动时,设置一个全局过滤器来捕获控制器存在但不存在操作的404,或者操作是否返回404结果。

        filters.Add(new HttpNotFoundFilterAttribute { Order = 99 });

其中过滤器是具有此覆盖的ActionFilterAttribute:

    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);
        }
    }

并且在Application_Error中,如果没有控制器存在:

        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);
             }

为避免处理404静态资源,您应该在Windows 7或Windows 2008 R2上安装SP1以升级IIS7并在web.config中设置:

...
<modules runAllManagedModulesForAllRequests="false">
...