2014-02-24 266 views
31

我们希望处理403错误,404错误,由于MySpecialDomainException而导致的所有错误,并为所有其他错误(包括IIS配置中的错误!)提供默认错误页面。所有的错误应该返回适​​当的剃刀视图,这将是非常好的在视图前面有一个ErrorControllerE.g.是这样的:ASP.NET MVC 5错误处理

public class ErrorController : Controller 
{ 
    public ViewResult NotFound() { return View(); } 
    public ViewResult Forbidden() { return View(); } 
    public ViewResult Default() 
    { 
     var ex = ObtainExceptionFromSomewhere(); 
     if(ex is MySpecialDomainException) 
      return View("MySpecialDomainException", new ErrorModel { Exception = ex }); 

     return View("GeneralError", new ErrorModel { Exception = ex }); 
    } 
} 

目前你找到许多不同的方式做到这一点在WWW上,一些最有可能过时。在这些:

  • Controller.OnException()
  • 错误过滤
  • 的customErrors在web.config中元素
  • 在Global.asax中的Application_Error事件处理

Q1:什么推荐的方式来满足ASP.NET MVC 5的要求?

此外我们想要捕获IIS主机中发生的错误。 Q2:为了防止IIS必须处理任何404s我们想添加一个匹配所有可能的URL的默认路由 - 这是值得推荐的吗?更好地注册IIS 404'以及?

问题3:甚至有可能注册一个返回控制器的IIS错误页面,或者只有IIS能够使用ASPX /静态HTML吗?

+0

我m好奇..当IIS配置不正确时,你会如何建议使用Razor页面?如果IIS不工作,剃刀不会工作... –

+0

是的,可能它甚至不可能。也许我们必须解决静态HTML @ IIS。所以可能最好是用ASP.NET MVC覆盖所有可能的URL,以防止404冒泡到IIS ... –

+0

http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET -MVC-methods-explaine –

回答

39

最好的方法是使用Global.Asax,因为您可以管理所有类型的错误(Ajax调用/所有意想不到的错误)。与其他人你不能这样做。

像这样:处理错误延伸的HandleError属性

protected void Application_Error() 
{ 
    HttpContext httpContext = HttpContext.Current; 
    if (httpContext != null) 
    { 
     RequestContext requestContext = ((MvcHandler)httpContext.CurrentHandler).RequestContext; 
     /* When the request is ajax the system can automatically handle a mistake with a JSON response. 
      Then overwrites the default response */ 
     if (requestContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      httpContext.Response.Clear(); 
      string controllerName = requestContext.RouteData.GetRequiredString("controller"); 
      IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); 
      IController controller = factory.CreateController(requestContext, controllerName); 
      ControllerContext controllerContext = new ControllerContext(requestContext, (ControllerBase)controller); 

      JsonResult jsonResult = new JsonResult 
      { 
       Data = new { success = false, serverError = "500" }, 
       JsonRequestBehavior = JsonRequestBehavior.AllowGet 
      }; 
      jsonResult.ExecuteResult(controllerContext); 
      httpContext.Response.End(); 
     } 
     else 
     { 
      httpContext.Response.Redirect("~/Error"); 
     } 
    } 
} 
+0

如何获取错误代码以便在ServerError =“500”或其他 –

+0

中以动态方式传递Application_Error是在您遇到意外异常时处理的代码,所以这意味着默认情况下您的响应结果将始终为500(内部服务器错误)。但是如果你想改变错误代码,你可以在你的代码中创建自定义的异常,并且在错误异常的基础上,你可以设置你想要的错误代码... – natnael88

+0

为什么我的响应结果总是500。哦,我想我想我错过了一件事。只有在有任何异常情况下才会调用Application_Error,如果发生404错误,它将不会被调用。我认为它更好地使用web.config的404错误 –

6

更好的办法。 处理错误的属性具有以下优点

  • 随着HandleErrorAttribute我们克服了异常 处理更多的控制。 HandleError允许我们在不同的控制器和操作中轻松处理不同的控制器和操作,在Application_Error 中获取此功能我们需要借助开关循环。

  • 一旦你进入的Application_Error你出MVC,你会失去 和ControllerContext那么我们不能做很多事情,会很容易 可能的的HandleError。

看到以下职位如何扩展错误处理属性和优势

Advantages of [HandleError] over Application_Error

http://maheshde.blogspot.com.au/2012/09/error-handing-with-mvc-using-custom.html

http://www.codeproject.com/Articles/731913/Exception-Handling-in-MVC

+0

感谢这个Mahesh!我已经在您的博客上留言(https://maheshde.blogspot.com.au/2012/09/error-handing-with-mvc-using-custom.html?showComment=1511493570513),因为我想知道如何拦截500个错误,并在某些情况下重新打包为404. – mattpm

38

没有金色的解决方案,所有的应用程序。

您可以在web.config中使用httpErrors显示友好的错误页面。与customErrors不同,这是一个IIS级别的设置,它甚至会向您显示一个友好的错误页面,以查看不在ASP.NET中的错误。

对于错误日志记录,我会建议去同一个的HttpModule像ELMAH: https://code.google.com/p/elmah/

我写了整个博客张贴关于这一点,在我解释的错误处理方式的不同: http://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

+1

从字面上看,第二段“您可以显示......”直接回答了这个问题。相比之下,没有链接列表。只有2个链接 - 第一个直接链接到ASP.NET中用于错误日志记录的常用工具的链接,第二个链接到冗长的博客文章,详细阐述了这个主题,但是甚至比这里提到的更多。包括这一点我没有看到任何伤害。感谢您的驯服。 – dustinmoris