WDu*_*ffy 123 application-error asp.net-mvc-3
我在global.asax
文件的Application_Error
事件中有代码,它在发生错误时执行,并将错误的详细信息发送给我自己.
void Application_Error(object sender, EventArgs e)
{
var error = Server.GetLastError();
if (error.Message != "Not Found")
{
// Send email here...
}
}
Run Code Online (Sandbox Code Playgroud)
我在Visual Studio中运行它时工作正常,但是当我发布到我们的实时服务器时,Application_Error
事件不会触发.
经过一些测试后,我可以Application_Error
在设置时进行射击customErrors="Off"
,但是将其设置回来可以customErrors="On"
阻止事件再次发射.
任何人都可以建议为什么Application_Error
在customErrors
启用时不会被解雇web.config
?
Jes*_*ebb 132
更新
由于这个答案确实提供了解决方案,我不会编辑它,但我找到了一种更清晰的方法来解决这个问题.请参阅我的其他答案了解详情......
原始答案:
我弄清楚为什么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
}
...
}
Run Code Online (Sandbox Code Playgroud)
默认情况下(生成新项目时),MVC应用程序在Global.asax.cs
文件中有一些逻辑.该逻辑用于映射路由和注册过滤器.默认情况下,它只注册一个过滤器:HandleErrorAttribute
过滤器.当customErrors打开时(或当设置为RemoteOnly时通过远程请求),HandleErrorAttribute告诉MVC查找错误视图,它从不调用该Application_Error()
方法.我找不到这方面的文档,但在programmers.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>
Run Code Online (Sandbox Code Playgroud)
此解决方案的问题在于它会对您的错误URL进行302重定向,然后这些页面以200状态代码进行响应.这导致谷歌索引错误页面,这是不好的.它也不符合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>
Run Code Online (Sandbox Code Playgroud)
此块告诉页面使用正确的状态代码.粗略的,在PageNotFound.aspx页面上,我使用了HttpStatusCode.NotFound
.我改变了我的web.config看起来像这样......
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx">
<error statusCode="404" redirect="~/PageNotFound.aspx" />
</customErrors>
Run Code Online (Sandbox Code Playgroud)
这一切都很完美!
摘要:
filters.Add(new HandleErrorAttribute());
Application_Error()
方法记录异常我已经注意到这个解决方案有几个缺点.
这些问题有解决办法,但我并不关心他们做任何额外的工作.
我希望这对大家有所帮助!
小智 69
我通过创建ExceptionFilter并在那里记录错误而不是Application_Error来解决这个问题.您需要做的就是在RegisterGlobalFilters中添加对in的调用
log4netExceptionFilter.cs
using System
using System.Web.Mvc;
public class log4netExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
Exception ex = context.Exception;
if (!(ex is HttpException)) //ignore "file not found"
{
//Log error here
}
}
}
Run Code Online (Sandbox Code Playgroud)
的Global.asax.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new log4netExceptionFilter()); //must be before HandleErrorAttribute
filters.Add(new HandleErrorAttribute());
}
Run Code Online (Sandbox Code Playgroud)
Jes*_*ebb 35
我发现了一篇文章,它描述了一种在MVC3 Web应用程序中制作自定义错误页面的更简洁的方法,它不会阻止记录异常的能力.
解决方案是使用<httpErrors>
该<system.webServer>
部分的元素.
我像我这样配置了我的Web.config ......
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
<error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>
Run Code Online (Sandbox Code Playgroud)
我也配置customErrors
了mode="Off"
(正如文章所建议的那样).
这使得响应被ErrorController的操作覆盖.这是控制器:
public class ErrorController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult NotFound()
{
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
这些视图非常简单,我只是使用标准的Razor语法来创建页面.
仅此一项就足以让您在MVC中使用自定义错误页面.
我还需要记录Exceptions,所以我偷了Mark使用自定义ExceptionFilter 的解决方案 ......
public class ExceptionPublisherExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext exceptionContext)
{
var exception = exceptionContext.Exception;
var request = exceptionContext.HttpContext.Request;
// log stuff
}
}
Run Code Online (Sandbox Code Playgroud)
您需要做的最后一件事是在Global.asax.cs文件中注册Exception Filter :
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ExceptionPublisherExceptionFilter());
filters.Add(new HandleErrorAttribute());
}
Run Code Online (Sandbox Code Playgroud)
这感觉就像一个比我之前的答案更清晰的解决方案,并且就我所知的情况而言同样有效.我喜欢它,特别是因为我觉得我不喜欢与MVC框架作斗争; 这个解决方案实际上利用了它!
在ASP.NET MVC5的情况下使用
public class ExceptionPublisherExceptionFilter : IExceptionFilter
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
public void OnException(ExceptionContext exceptionContext)
{
var exception = exceptionContext.Exception;
var request = exceptionContext.HttpContext.Request;
// HttpException httpException = exception as HttpException;
// Log this exception with your logger
_logger.Error(exception.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
你可以找到它FilterConfig.cs
的App_Start
文件夹中.
归档时间: |
|
查看次数: |
50766 次 |
最近记录: |