更新
由于此答案确实提供了解决方案,因此我将不对其进行编辑,但是我找到了解决此问题的更简洁的方法。查看我的其他答案以获取详细信息...
原始答案:
我想出了为什么Application_Error()
不调用该方法的原因...
Global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute()); // this line is the culprit
}
...
}
默认情况下(生成新项目时),MVC应用程序在Global.asax.cs
文件中具有某些逻辑。此逻辑用于映射路由和注册过滤器。默认情况下,它仅注册一个过滤器:一个HandleErrorAttribute
过滤器。当customErrors启用时(或在设置为RemoteOnly时通过远程请求),HandleErrorAttribute告诉MVC查找错误视图,并且从不调用该Application_Error()
方法。我找不到有关此操作的文档,但对此内容的解释是在developers.stackexchange.com上。
要获得针对每个未处理的异常调用的ApplicationError()方法,只需删除注册HandleErrorAttribute过滤器的行即可。
现在的问题是:如何配置customErrors以获取所需的信息...
customErrors部分默认为redirectMode="ResponseRedirect"
。您也可以将defaultRedirect属性指定为MVC路由。我创建了一个非常简单的ErrorController,并将web.config更改为如下所示...
web.config
<customErrors mode="RemoteOnly" redirectMode="ResponseRedirect" defaultRedirect="~/Error">
<error statusCode="404" redirect="~/Error/PageNotFound" />
</customErrors>
此解决方案的问题在于,它会执行302重定向到您的错误URL,然后这些页面会以200状态代码进行响应。这导致Google将错误页面编入索引,这是很糟糕的。它也不十分符合HTTP规范。我要做的是不重定向,而是使用我的自定义错误视图覆盖原始响应。
我试图改变redirectMode="ResponseRewrite"
。不幸的是,此选项不支持MVC路由,仅支持静态HTML页面或ASPX。我最初尝试使用静态HTML页面,但是响应代码仍为200,但至少没有重定向。然后我从这个答案中得到了一个主意...
我决定放弃使用MVC进行错误处理。我创建了Error.aspx
和PageNotFound.aspx
。这些页面非常简单,但是却具有魔力……
<script type="text/C#" runat="server">
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Response.StatusCode = (int) System.Net.HttpStatusCode.InternalServerError;
}
</script>
该块告诉页面要提供正确的状态代码。粗略地说,我HttpStatusCode.NotFound
改用PageNotFound.aspx页。我将web.config更改为如下所示...
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx">
<error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>
一切都很好!
摘要:
- 删除行:
filters.Add(new HandleErrorAttribute());
- 使用
Application_Error()
方法记录异常
- 将customErrors与ResponseRewrite一起使用,指向ASPX页面
- 使ASPX页面负责其自己的响应状态代码
我注意到此解决方案有两个缺点。
- ASPX页面无法与Razor模板共享任何标记,我不得不重写我们网站的标准页眉和页脚标记,以实现一致的外观。
- * .aspx页可以通过点击其URL直接访问
有解决这些问题的方法,但是我对它们的担心并不足够,无法做任何额外的工作。
希望对大家有帮助!