我对Global.asax进行了一些修改,以便我可以显示自定义错误页面(403,404和500)以下是代码:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
//FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_Error(object sender, EventArgs e)
{
if (Context.IsCustomErrorEnabled)
{
ShowCustomErrorPage(Server.GetLastError());
}
}
private void ShowCustomErrorPage(Exception exception)
{
HttpException httpException = exception as HttpException;
if (httpException == null)
{
httpException = new HttpException(500, "Internal Server Error", exception);
}
Response.Clear();
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("fromAppErrorEvent", true);
switch (httpException.GetHttpCode())
{
case 403:
routeData.Values.Add("action", "AccessDenied");
break;
case 404:
routeData.Values.Add("action", "NotFound");
break;
case 500:
routeData.Values.Add("action", "ServerError");
break;
default:
routeData.Values.Add("action", "DefaultError");
routeData.Values.Add("httpStatusCode", httpException.GetHttpCode());
break;
}
Server.ClearError();
IController controller = new ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
}
我还在Web上添加了以下内容.Config:
<customErrors mode="On">
<!-- There is custom handling of errors in Global.asax -->
</customErrors>
自定义错误页面正确显示,ELMAH将正确记录(故意)抛出的错误。但是,ELMAH还会捕获并记录一个额外的错误:
System.InvalidOperationException: The view 'Error' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/account/Error.aspx ~/Views/account/Error.ascx ~/Views/Shared/Error.aspx ~/Views/Shared/Error.ascx ~/Views/account/Error.cshtml ~/Views/account/Error.vbhtml ~/Views/Shared/Error.cshtml ~/Views/Shared/Error.vbhtml
我的第一直觉让我在过滤器配置中禁用全局HandleErrorAttribute
。而且,类似的问题如:MVC problem with custom error pages让我相信我的怀疑是对的。但即使在禁用全局HandleErrorAttribute
之后,我仍然收到错误,无法找到错误视图!是什么赋予了?我唯一的另一个预感是我的基本控制器来自System.Web.Mvc.Controller
我试图检查来源以查看HandleErrorAttribute
是否适用于System.Web.Mvc.Controller
但是无法收集任何内容......
更新: 我尝试覆盖我的基本控制器,将异常标记为如下处理:
protected override void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
base.OnException(filterContext);
}
但这并没有解决问题。
UPDATE2:
我将一个Error.aspx文件放入共享视图中,只是为了看看会发生什么。当它在那里时,ELMAH记录强制异常,然后提供共享视图 - 它永远不会到达Application_Error()
....不太确定该怎么做。
答案 0 :(得分:27)
终于让它满意了......
Elmah.Mvc包应用“隐藏”错误处理程序。我已通过在web.config <appSettings>
中添加以下行来禁用此功能(默认情况下,该值从nuget install设置为“false”)
<add key="elmah.mvc.disableHandleErrorFilter" value="true" />
所以,现在我的错误传播到Application_Error并由Elmah记录,绕过Elmah过滤器,并显示正确的错误页面(不是/shared/error.cshtml中的那个)
答案 1 :(得分:1)
如果您在IIS 7集成模式下运行,则需要在Application_Error中添加Response.TrySkipIisCustomErrors = true;
。否则,IIS仍然会将客户端重定向到自定义错误页面,尽管您在代码中执行了任何操作。
有关其他详细信息,请参阅此处:http://www.west-wind.com/weblog/posts/2009/Apr/29/IIS-7-Error-Pages-taking-over-500-Errors
编辑:这是我的Application_Error的主体:
if (HttpContext.Current != null)
{
Server.ClearError();
Response.TrySkipIisCustomErrors = true;
RouteData data = new RouteData();
data.Values.Add("controller", "Error");
data.Values.Add("action", "Error");
IController controller = new MyApp.Controllers.ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(Context), data));
}