更整洁的异常处理





0/5 (0投票)
ASP.net 提供了在 web.config 中指定异常发生时的错误页面的功能,例如: <customErrors
ASP.net 提供了在 web.config 中指定异常发生时的错误页面的功能,例如
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="~/error-generic.aspx">
<error statusCode="403" redirect="~/error-403.aspx" />
<error statusCode="404" redirect="~/error-404.aspx" />
</customErrors>
</system.web>
此示例将错误 403 和 404 重定向到特定页面,并将所有其他错误重定向到通用页面。这在大多数情况下都很好用,但它存在几个问题
1. 它不允许自定义日志记录,并且
2. 由于页面提供方式,它返回的 HTTP 状态为 200,而不是 500(或更有用的状态)。
但是,这两个问题都可以使用自定义 HttpModule 来处理错误,从而轻松克服。首先,创建一个新类
public class ErrorModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.Error += new EventHandler(Context_Error);
}
public void Context_Error(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
SystemWebSectionGroup systemWeb = (SystemWebSectionGroup)configuration.GetSectionGroup("system.web");
CustomErrorsSection customErrorsSection = systemWeb.CustomErrors;
// 如果 customerrors 模式 == 关闭,那么就让 IIS 处理它
if (customErrorsSection.Mode != CustomErrorsMode.Off)
{
// 如果模式 == 开启或它是一个远程请求,我们想要获取漂亮的页面
if (customErrorsSection.Mode == CustomErrorsMode.On || !context.Request.IsLocal)
{
Exception ex = context.Error;
HttpException httpException = (HttpException)ex;
string sURL = customErrorsSection.DefaultRedirect;
if (httpException != null)
{
context.Response.StatusCode = httpException.GetHttpCode();
CustomErrorCollection customErrorsCollection = customErrorsSection.Errors;
CustomError customError = customErrorsCollection[context.Response.StatusCode.ToString()];
if (customError != null)
sURL = customError.Redirect;
// 记录实际原因
ex = httpException.GetBaseException();
}
else
{
context.Response.StatusCode = 500;
}
/*
在此处添加自定义日志记录!
*/
context.ClearError();
context.Server.Transfer(sURL);
}
}
}
}
然后,在 web.config 中,添加以下内容
<system.web>
<httpModules>
<add name="ErrorModule" type="ErrorModule" />
</httpModules>
</system.web>
当 ISS 加载应用程序时,它会加载 ErrorModule 类并执行其 Init() 方法,该方法为 Application.Error 事件添加自定义处理程序。处理程序是奇迹发生的地方。
首先,它读取 web.config 的 customErrors 部分,以便可以使用您的设置。接下来,它检查错误模式,以便在您不想绕过默认错误页面时,它只会返回而不做任何事情。
设置默认错误 URL 后,它会检查错误是否为 HttpException,如果是,它会将响应 HTTP 状态设置为异常返回的代码,并根据您在 customErrors 部分中定义的任何自定义页面检查该代码。如果找到匹配项,它将使用 web.config 中的 URL 更新该 URL。如果它不是 HttpException,则将 HTTP 状态设置为 500(内部服务器错误)。此时,您可以添加自定义错误日志记录。然后,它会清除错误,以便 IIS 不会执行它的操作,并重定向到所选页面。