一般对于网站不可访问,比如页面不存在或者是页面报错,这种一般都是伪静态页面的在执行动态语言的时候出错了,或者找不到对应的文章。我们不可能在每个出错的页面都写上"Response.StatusCode = (int)HttpStatusCode.NotFound;"的状态码的响应。所以这里需要有个统一的全局错误处理的机制,在所有的页面错误记录在日志中,并且返回404的状态码,这样可以通过IIS错误页面的设置成友好的404的自定义页面,这样能满足页面的友好和SEO的友好。
一般的开发人员以为通过webconfig中的Custom Errors的配置就能实现404的友好页面,但是这里的状态码不是404,而是302的重定向,影响搜索引擎的优化,另外还有会造成用户反馈问题时提供的是重定向后的URL,这样开发人员无法快速定位问题,同时也会造成用户无法通过刷新浏览器进行重试,或者问题解决后通过刷新浏览器无法恢复正常。这种实现方式不太理想。要在ASP.NET中处理好自定义错误首先要放弃使用web.config\customErrors的设置。
对于ASP.NET MVC中我们可以在Global.asax中注册Application_Error 的事件,在全局的错误事件做好错误页面的自定义处理。例如下面代码所示,如果页面出错就会统一返回404状态码。
protected void Application_Error(Object sender, EventArgs e)
{
Exception lastError = Server.GetLastError();
if (lastError != null)
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
Response.Write("NotFound");
Server.ClearError();
}
}
这里就保证了页面出错的时候就会统一返回404状态码,这里只要配合IIS的错误页的设置指定到网站目录下的404.html 的文件就可以实现了既能显示404友好页面,也能返回404的状态码。
如有需要,可以在网站程序级别就可以实现最理想的404的设置,不需要通过IIS进行设置。
if (httpCode == 400 || httpCode == 404)
{
Response.StatusCode = 404;
//跳转到指定的静态404信息页面,根据需求自己更改URL
Response.WriteFile("~/HttpErrorPage/404.html");
Server.ClearError();
return;
}
通过在Global.asax中注册Application_Error 的事件中实现错误信息的自定义是处理自定义错误的最理想的方式。
附上Application_Error的处理的参考例子。这里在发生页面错误的时候
protected void Application_Error(Object sender, EventArgs e)
{
Exception lastError = Server.GetLastError();
if (lastError != null)
{
//异常信息
string strExceptionMessage = string.Empty;
//对HTTP 404做额外处理,其他错误全部当成500服务器错误
HttpException httpError = lastError as HttpException;
if (httpError != null)
{
//获取错误代码
int httpCode = httpError.GetHttpCode();
strExceptionMessage = httpError.Message;
if (httpCode == 400 || httpCode == 404)
{
Response.StatusCode = 404;
//跳转到指定的静态404信息页面,根据需求自己更改URL
// 通过用Response.WriteFile方法跳转到指定静态页面
Response.WriteFile("~/HttpErrorPage/404.html");
Server.ClearError();
return;
}
}
strExceptionMessage = lastError.Message;
/*-----------------------------------------------------
* 这里代码可根据实际需要记录日志,或处理其他业务流程
* ---------------------------------------------------*/
/*
* 跳转到指定的http 500错误信息页面,根据需求自己更改URL
* 通过用Response.WriteFile方法跳转到指定静态页面
*/
Response.StatusCode = 500;
Response.WriteFile("~/HttpErrorPage/500.html");
//一定要调用Server.ClearError()否则会触发错误详情页
Server.ClearError();
Server.Transfer("~/HttpError/500.aspx");
}
}