我正在尝试让[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确实更改了标志。
所以,让我们来看看可能性:
仅安装了全局处理程序。
安装了全局处理程序,以及操作的处理程序
安装了全局处理程序,并且操作和控制器上的处理程序:以相同的方式工作。所有三个都被称为,第一个动作,然后是控制器,然后是全局。因为操作上的处理程序将ExceptionHandled设置为true,后两者什么都不做,我们得到错误页面。
所有这些与我昨天看到的行为完全不一致,当我设置customErrors时,仍然看到IsCustomErrorEnabled为false。我没有解释,除了IIS Express卡住的可能性,并且不再识别web.config中的更改。