【问题标题】:ASP.NET MVC 5 error handlingASP.NET MVC 5 错误处理
【发布时间】:2014-03-26 11:16:14
【问题描述】:

我们要处理 403 错误、404 错误以及由 MySpecialDomainException 引起的所有错误,并为所有其他错误(包括 IIS 配置中的错误!)提供默认错误页面。所有错误都应该返回正确的 Razor 视图,在视图前面有一个 ErrorController 会非常好。 例如这样的:

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()
  • 错误过滤器
  • web.config 中的 customErrors 元素
  • 在 Global.asax 的 Application_Error 中处理

Q1:使用 ASP.NET MVC 5 满足我们要求的推荐方法是什么?

我们还想捕捉 IIS 主机中发生的错误。 Q2:为了防止 IIS 必须处理任何 404,我们考虑添加一个匹配所有可能 URL 的默认路由 - 这是否值得推荐?最好也注册 IIS 的 404?

Q3:是否可以注册一个返回到控制器的 IIS 错误页面,或者 IIS 是否仅支持 ASPX/静态 HTML?

【问题讨论】:

  • 我很好奇.. 当 IIS 配置不正确时,您究竟会如何建议拥有 Razor 页面?如果 IIS 不工作,Razor 将无法工作......
  • 是的,可能这根本不可能。也许我们必须满足于静态 HTML @ IIS。所以最好用 ASP.NET MVC 覆盖所有可能的 URL,以防止 404 冒泡到 IIS...
  • @Liam 提供的 Microsoft 页面比 MVC 更适合 Web 窗体。

标签: c# asp.net-mvc error-handling asp.net-mvc-5 asp.net-mvc-5.1


【解决方案1】:

最好的方法是使用 Global.Asax,因为您可以管理所有类型的错误(Ajax 调用/所有意外错误)。和别人一起你做不到。

像这样:

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

【讨论】:

  • 我怎样才能让错误代码在 ServerError="500" 或其他中作为动态传递
  • Application_Error 仅在您的代码中出现意外异常时处理,因此这意味着默认情况下您的响应结果将始终为 500(内部服务器错误)。但是如果您想更改错误代码,您可以在代码中创建自定义异常,并在您获得的错误异常的基础上设置您想要的错误代码...
  • 为什么我的响应结果总是 500 。哦,我想我错过了一件事。 Application_Error 只会在有任何异常时才会被调用,它不会在 404 错误的情况下被调用.---------我认为最好使用 web.config 来处理 404 错误
  • 对不起,你是对的..,你可以管理 MVC 页面中的所有意外错误,不仅仅是 500(当然,如果你有代码异常总是 500(内部服务器错误))。这是代码: HttpException serverError = Server.GetLastError() as HttpException; if (serverError !=null) { int errorCode = serverError.GetHttpCode(); }
  • 请注意,使用此解决方案,所有 AJAX 调用(包括调用不存在的端点)显然都会成功。您需要解开响应数据以处理故障。
【解决方案2】:

没有适用于所有应用程序的黄金解决方案。

您可以使用 web.config 中的 httpErrors 显示友好的错误页面。与 customErrors 不同,这是一个 IIS 级别设置,甚至会为您显示一个友好的错误页面,用于显示非 ASP.NET 内部的错误。

对于错误记录,我建议使用像 ELMAH 这样的 HttpModule: https://code.google.com/p/elmah/

我为此写了一篇完整的博客文章,并在其中解释了错误处理的不同方式: http://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging

【讨论】:

  • 从字面上看,第二段“您可以显示...”直接回答了这个问题。相反,没有链接列表。只有 2 个链接 - 第一个链接直接指向 ASP.NET 中用于错误记录的常用工具,第二个链接指向详细阐述此主题的冗长博客文章,但比这里所要求的还要多。我认为包含这个没有任何害处。不过感谢您的拖钓。
【解决方案3】:

处理错误的更好方法是扩展handleerror 属性。 处理错误属性有以下优点

  • 使用 HandleErrorAttribute,我们可以更好地控制异常 处理。 HandleError 允许我们以不同的方式处理错误 Application_Error 中的不同控制器和操作很容易 要获得此功能,我们需要借助 switch 循环。

  • 一旦您进入 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

【讨论】:

  • 感谢马赫什!我在您的博客 (maheshde.blogspot.com.au/2012/09/…) 上发表了评论,因为我想知道如何拦截 500 错误并在某些情况下重新打包为 404。
猜你喜欢
  • 2017-05-31
  • 2010-09-16
  • 2018-02-27
  • 2017-03-16
  • 2011-06-10
  • 2012-10-04
  • 2010-09-11
  • 2015-10-02
  • 2013-02-24
相关资源
最近更新 更多