【发布时间】:2012-05-20 16:17:03
【问题描述】:
我正在尝试为 MVC 3 项目处理 global.asax 中的所有应用程序异常,虽然在 Cassini 中一切正常,但一旦我部署到 IIS 7.5,IIS 就开始从我的应用程序中控制并处理许多异常本身。这会导致绕过我的自定义日志记录并返回丑陋的视图。
我对 Darin 的 answer 到 this question 有类似的方法。这是我目前正在使用的。
protected void Application_Error(object sender, EventArgs e)
{
var app = (MvcApplication)sender;
var context = app.Context;
var exception = app.Server.GetLastError();
LogExceptionDetails(exception, Request.Url.PathAndQuery);
context.Response.Clear();
context.ClearError();
string redirectTo = "/error";
HttpException httpException = exception as HttpException;
if (httpException != null)
{
switch (httpException.GetHttpCode())
{
case 403:
redirectTo += "/forbidden";
break;
case 404:
redirectTo += "/notfound";
break;
}
}
Response.TrySkipIisCustomErrors = true;
// I should really change this so I can return a proper statusCode
Response.Redirect(redirectTo);
}
例如,导航到localhost/app_code 将返回一个丑陋的视图并且不会被记录。我已经设法至少让 IIS 使用以下方法返回我的自定义视图:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<error statusCode="403" path="/error/forbidden" responseMode="ExecuteURL" />
<remove statusCode="404" />
<error statusCode="404" path="/error/notfound" responseMode="ExecuteURL" />
</httpErrors>
但这并不能解决日志记录问题。
我尝试过的其他事情包括:
- 设置
existingResponse="PassThrough"。 - 使用
<clear />。 -
httpErrors有和没有customErrors的各种组合。 - 设置
<modules runAllManagedModulesForAllRequests="true" />。 Response.TrySkipIisCustomErrors = true;
有没有办法以编程方式处理这个问题,同时将事情集中在 global.asax 中,而不是搞乱 web.config?
【问题讨论】:
-
您有什么理由不在控制器上使用
[HandlesError]并在那里进行操作? Application_Error 应该是万不得已的后备方案... -
@bhamlin 几乎我所见过的关于 MVC 3 异常处理的每个示例都使用了
Application_Error和/或ErrorController。话虽如此,我实际上删除了过滤器,因为它正在吞噬远程异常,这使得调试更加困难,但那是在以这种方式实现之后。 -
@bhamlin,HandlesError 只处理发生在控制器动作中的错误,而不是当它例如找不到控制器时。
标签: asp.net-mvc-3 c#-4.0 exception-handling iis-7.5