65.9K
CodeProject 正在变化。 阅读更多。
Home

更整洁的异常处理

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2013 年 10 月 11 日

CPOL

2分钟阅读

viewsIcon

5287

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 不会执行它的操作,并重定向到所选页面。

© . All rights reserved.