CustomErrors为On,为什么IsCustomErrorEnabled仍为false?

时间:2014-02-18 22:43:59

标签: asp.net-mvc asp.net-mvc-4 web-config

我正在尝试让[HandleError]在MVC4应用程序中运行。我在控制器中抛出异常,我仍然看到黄色的“服务器错误”页面。

为了帮助弄清楚发生了什么,我创建了自己的过滤器属性:

public class MyHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        bool isHandled = filterContext.ExceptionHandled;
        bool customErrorEnabled = filterContext.HttpContext.IsCustomErrorEnabled;
        bool debuggingErrorEnabled = filterContext.HttpContext.IsDebuggingEnabled;

        base.OnException(filterContext);
    }
}

我在base.OnException()上粘贴了一个断点,然后让它发送。

当我的控制器抛出异常时,会调用MyHandleErrorAttribute.OnException - 但是customErrorEnabled为false。我使用Resharper检查Microsoft的HandleErrorAttribute.OnException()中的代码,它以:

开头
public virtual void OnException(ExceptionContext filterContext)
{
    if (filterContext == null)
        throw new ArgumentNullException("filterContext");
    if (filterContext.IsChildAction || filterContext.ExceptionHandled || 
            !filterContext.HttpContext.IsCustomErrorEnabled)
        return;

    // ...
}

换句话说,如果filterContext.HttpContext.IsCustomErrorEnabled为false,则故意无效。

所以,问题是 - 为什么IsCustomErrorEnabled为false?

一个显而易见的可能性是,在web.config中。但如果这是真的,我不知道如何。我在整个项目中搜索了“customErrors”,它只出现在根web.config中,并且显式设置为“On”:

<system.web>
    <customErrors mode="On" />
    ...
</system.web>

那么,IsCustomErrorEnabled如何仍然是假的?还有什么可以超越它?我应该在哪里看?

================添加的其他信息================

一点混淆 - HandleErrorAttribute被注册为全局过滤器。为了探索这些东西是如何工作的,我创建了三个不同的自定义异常过滤器:

public class MyGlobalHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        bool isHandled = filterContext.ExceptionHandled;
        bool customErrorEnabled = filterContext.HttpContext.IsCustomErrorEnabled;
        bool debuggingErrorEnabled = filterContext.HttpContext.IsDebuggingEnabled;

        base.OnException(filterContext);
    }
}

public class MyControllerHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        bool isHandled = filterContext.ExceptionHandled;
        bool customErrorEnabled = filterContext.HttpContext.IsCustomErrorEnabled;
        bool debuggingErrorEnabled = filterContext.HttpContext.IsDebuggingEnabled;

        base.OnException(filterContext);
    }
}

public class MyActionHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        bool isHandled = filterContext.ExceptionHandled;
        bool customErrorEnabled = filterContext.HttpContext.IsCustomErrorEnabled;
        bool debuggingErrorEnabled = filterContext.HttpContext.IsDebuggingEnabled;

        base.OnException(filterContext);
    }
}

当然,其中一个我在一个动作上配置,一个在其控制器上,一个在全局上。这样我就可以知道哪个被调用,以及按什么顺序。

所以,如果我设置了所有这三个,那么无论是否在web.config中设置,所有三个都被调用,操作,然后是控制器,然后是全局。 (在本地调试中运行VS2012,针对IIS Express。)但customErrors确实更改了标志。

所以,让我们来看看可能性:

  • 仅安装了全局处理程序。

    • customErrors Off:使用ExceptionHandled false和IsCustomErrorEnabled false调用全局处理程序,因此它什么都不做,我们得到黄色的Server Error页面。
    • customErrors On:使用ExceptionHandled false和IsCustomErrorEnabled调用全局处理程序为true,因此HandleErrorAttribute执行它所做的操作,并加载〜/ Views / Shared / Error.cshtml。
  • 安装了全局处理程序,以及操作的处理程序

    • customErrors Off:使用ExceptionHandled false和IsCustomErrorEnabled false调用属性处理程序,因此它什么都不做,然后使用ExceptionHandled false和IsCustomErrorEnabled false调用全局处理程序,因此它也什么都不做,我们得到黄色服务器错误页。
    • customErrors On:使用ExceptionHandled false和IsCustomErrorEnabled调用属性处理程序,因此它执行它所做的事情,然后使用ExceptionHandled为true并且IsCustomErrorEnabled为true调用全局处理程序,因此它不执行任何操作,因为属性处理程序已经处理它。我们得到〜/ Views / Shared / Error.cshtml。
  • 安装了全局处理程序,并且操作和控制器上的处理程序:以相同的方式工作。所有三个都被称为,第一个动作,然后是控制器,然后是全局。因为操作上的处理程序将ExceptionHandled设置为true,后两者什么都不做,我们得到错误页面。

所有这些与我昨天看到的行为完全不一致,当我设置customErrors时,仍然看到IsCustomErrorEnabled为false。我没有解释,除了IIS Express卡住的可能性,并且不再识别web.config中的更改。

0 个答案:

没有答案