ASP.net MVC [HandleError]无法捕获异常

40

在两个不同的应用程序中,一个是自定义的,另一个是新的VS2008 MVC项目中提供的示例MVC应用程序,[HandleError]未捕获异常。

在示例应用程序中:

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        throw new Exception();
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

这只是默认控制器,为了测试而抛出异常。

但它不起作用。 它没有进入默认的error.aspx页面,而是在浏览器中显示调试信息。

问题首先出现在我正在开发的自定义应用程序中,这促使我测试示例应用程序。 我认为它与我在自定义应用程序中做的更改有关,因此除了index方法中的throw之外(呕吐),我完全没有更改示例应用程序。

我被难住了。 我错过了什么?

6个回答

70
在Web.config中更改customErrors:
<system.web>
  <customErrors mode="On">
  </customErrors>
如果模式为"Off"或"RemoteOnly",则您将看到黄色的死亡屏幕而不是自定义错误页面。这样做的原因是开发人员通常希望在黄色的死亡屏幕上看到更详细的信息。

4
我做了这件事,但它没有成功。我发现在MVC2应用程序的默认模板中有不止一个Web.config文件。你需要将customErrors标签应用到解决方案中最根本的Web.config文件中。 - Mike
@Mike,所有MVC版本都是如此。 - Craig Stuntz
对我没有用,请检查我的问题:https://dev59.com/smXWa4cB1Zd3GeqPNHrh - user20358

16

重要提示:请注意您的错误页面本身不要有错误!

如果有错误,您将会看到ASP.NET的自定义错误页面,并陷入无限循环和困境。请清除页面中可能引起错误的所有内容并进行测试。

此外,关于'customErrors'开启或关闭,是否显示友好错误页面(即您的Errors.aspx)取决于几个因素。

请参考此博客(除下面所述之外)

HttpContext.IsCustomErrorEnabled - 查看三个不同的来源

  1. web.config文件的“deployment”元素的retail属性。在将应用程序部署到生产服务器时设置此属性非常有用。这会覆盖任何其他自定义错误设置。
  2. web.config文件的“customErrors”元素的模式属性。此设置指示是否完全启用了自定义错误,如果启用了,则仅对远程请求启用。
  3. HttpRequest对象的IsLocal属性。如果只有远程请求才启用了自定义错误,则需要知道请求是否来自远程计算机。

这里的想法是,您可以在开发过程中关闭'customErrors' - 当您希望查看错误时,然后仅在生产环境中启用它。

MSDN文章进一步讨论了该属性。


13

这个问题的另一个原因可能是:

在由 VS2008 / VS2008 Express 生成的模板 MVC 应用程序中,Error.aspx(由 VS 生成)使用主页。如果主页访问任何 ViewData,则会引发空引用异常,然后 error.aspx 将无法显示。

请使用此简单代码作为您的 Error.aspx ,它将解决该问题(以及 CustomErrors=On)

<%@ Page Language="C#"  Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
<%= Model.Exception.Message %>

4
"If Master Page access any ViewData it will throw null reference Exception" 这句话让我恢复了理智。谢谢! 如果主控制页面访问任何视图数据,它会引发空引用异常。 - Marco M.

8

我也曾经遇到过这个问题,现在我相信我已经理解了这个问题。

简而言之,让 [HandleError] 正常工作的要求是:

你必须在 web.config 中启用自定义错误,并且还必须指定错误视图在 <customErrors> 标记中的位置。

例如:

<customErrors mode="On" defaultRedirect="Error" />

略去defaultRedirect="Error"部分,浏览器会出现500错误,而非ASP.NET错误页面(YSOD)。
此外,您不必处于发布模式。我用Debug构建进行了测试,结果很好。
我的环境是Visual Studio 2010,使用.NET 4和标准的“ASP.NET MVC 2 Web Application”项目模板。
让我困惑的是HandleErrorAttribute类的MSDN文档。它并没有明确说明您必须在web.config中打开自定义错误。我认为我只需要[Handle Error]属性。

已经尝试了这个方法,但仍然存在相同的问题。更多细节请参见:https://dev59.com/smXWa4cB1Zd3GeqPNHrh - user20358

5

我曾经遇到过一些愚蠢的情况,可能对某些人有所帮助。

请确保已将<customErrors mode="On" />添加到正确的web.config文件中。


有时候(特别是当您使用诸如Resharper之类的工具,并通过键入文件名而不是通过Solution Explorer打开文件时),您可能会从Views文件夹或甚至从另一个项目中打开web.config文件。


我永远不会知道为什么他们决定需要两个Web配置文件 :( - martijn
“第二个”是针对 Razor 引擎本身的。可能你可以将你的视图放在任何地方,因此该项目可能没有 web.config(与 Web 项目不同),或者您想要单独的设置。 我同意,为了防止编码中出现这样的错误,可能可以用其他方式完成,但一般来说这是有意义的。 - Agat

2
注意:在我的情况下,我试图让HandleError属性捕捉在Controller构造函数中抛出的异常!当然它不会捕捉到。 HandleError属性只能捕捉在Controller 操作中抛出的异常。这在MSDN页面上很清楚(应该多注意一下):

表示用于处理由操作方法引发的异常的属性。

另外一个问题是ControllerOnException(ExceptionContext exceptionContext)重写方法从未被调用。同样的道理:因为我在Controller的构造函数中抛出了异常,所以它自然不会被调用。
我花了1个小时来解决这个问题。 :o) 希望它对下一个人有帮助...
提示:记住,HandleError属性只能捕捉500错误。对于其他错误,您应该在Web.config中声明<customErrors>部分:
<customErrors mode="On">
  <error statusCode="403" redirect="~/403" />
  <error statusCode="404" redirect="~/404" />
</customErrors>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接