【问题标题】:Application_Error() not firingApplication_Error() 未触发
【发布时间】:2016-11-12 18:54:29
【问题描述】:

我正在尝试运行将异常记录到数据库的 ASP.NET 应用程序。我正在使用 Application_Error 来捕获异常。

在添加连接字符串之前,为了测试我的代码(Logger 类和 Global.asax 中的代码),我尝试将错误记录到 Windows 事件查看器。这按预期工作。

但是在将连接字符串添加到 Web.config 文件并添加 ADO.NET 代码之后,我尝试运行该应用程序。但是我得到了黄屏死机:D

我不知道我的代码有什么问题。我只修改了 Web.config 文件中的 connectionStrings 元素,并添加了 ADO.NET 代码。

这是代码。

这是 Page_Load 事件中的 Web 表单代码。 Country.xml 文件不存在,预计会引发错误。

DataSet dataset = new DataSet();
dataset.ReadXml(Server.MapPath("~/Countries.xml"));
GridView1.DataSource = dataset;
GridView1.DataBind();

Application_Error

Exception exception = Server.GetLastError();
if (exception != null)
{
Logger.Log(exception);
Server.ClearError();
Server.Transfer("~/Errors.aspx");
}

Web.config

<configuration>
<connectionStrings>
    <add name="DBCS" connectionString="Data Source=.;database=Sample;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  </connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
</system.web>
</configuration>

我尝试通过在 Global.asax 中的 Application_Error 方法处放置断点来进行调试,但控件从未到达该点。 该异常由 Page_Load 事件触发。 Logger 类代码中没有编译错误。 另外,我不想使用 customErrors 路由来解决这个问题。

提前致谢。

这是代码的链接: https://drive.google.com/folderview?id=0B5K22Q9r50wXU0VOQmJKVHBoaDg&usp=sharing

【问题讨论】:

  • 您是否也在实现自定义错误页面?您是否确认没有其他可能在 Application_Error 代码之前首先捕获异常的 try-catch 语句?
  • 嗨@Ephraim,是的,我正在实现一个自定义错误页面:Errors.aspx。我的代码中没有其他 try catch 块。异常没有得到处理,我看到了黄屏死机。

标签: c# asp.net logging


【解决方案1】:

在我的情况下,我在这个事件处理程序中有错误日志记录(sentry.io),并且日志记录算法本身导致错误,因此重定向到 web.config 中定义的错误页面,我也认为它没有触发。确保在错误处理程序中也对代码使用 try-catch 以调试案例。 IE。刷新异常详细信息作为响应并结束响应。

这是我到 sentry.io 的错误记录器:

public static void LogException(Exception ex, bool redirect = true)
{
    if (ex != null)
    {
        if (HttpContext.Current.Request.IsLocal)
        {
            throw ex;
        }

        // ignore Response.Redirect errors
        if (ex.GetType() == typeof(ThreadAbortException))
        {
            return;
        }

        var sentryApiKey = GetAppSetting("SentryIO.ApiKey");

        if (string.IsNullOrEmpty(sentryApiKey))
        {
            throw new NullReferenceException("SentryIO.ApiKey not defined as app setting.");
        }

        var ravenClient = new RavenClient(sentryApiKey);
        ravenClient.Capture(new SentryEvent(ex));

        if (redirect)
        {
            HttpContext.Current.Response.StatusCode = 404;
            HttpContext.Current.Response.Redirect("/?500-error-logged");
        }
    }
}

正如我所见,在发布模式下构建或具有如下所示的 web.config,并不能阻止此事件触发。

<compilation debug="false" targetFramework="4.5.2" />
<customErrors mode="RemoteOnly" defaultRedirect="errordocs/500.htm">
    <error statusCode="403" redirect="errordocs/403.htm" />
    <error statusCode="404" redirect="errordocs/404.htm" />
</customErrors>

【讨论】:

    【解决方案2】:

    您是否在 web.config 上启用了自定义错误?

    <system.web>
        ...
        <customErrors mode="RemoteOnly" defaultRedirect="~/Errors.aspx" redirectMode="ResponseRewrite" />
        ...
    </system.web>
    

    请注意,重定向模式为“ResponseRewrite”,以保留Server.GetLastError() 异常。如果你设置了这个,那么Server.GetLastError() 将返回 null。

    在 Global.asax 中实现 Application_Error 应该很容易......

    protected void Application_Error(Object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();
        if (ex is ThreadAbortException)
            return; // Redirects may cause this exception..
        Logger.Error(LoggerType.Global, ex, "Exception");
        Response.Redirect("unexpectederror.htm");
    }
    

    更新:

    一个可能的罪魁祸首是在 Global.asax 上注册为过滤器的 HandlerErrorAttribute。

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute()); // this line is the culprit
    }
    

    只需注释掉或删除该行,并确保您已在 web.config 下的 system.web 中实现 customErrors。

    我对 HandleErrorAttribute 不太熟悉,如果这能解决您的问题,那么不妨查看它的文档。

    【讨论】:

    • 嗨@Ephraim,你的方法会奏效,这将帮助我捕捉到异常。但是,我正在使用的代码和方法出了什么问题,这是我的问题。当未使用 try-catch 块或在页面级别处理异常时,应触发 Application_Error。那么为什么这不起作用呢?
    • @Nachiket 我更新了我的答案。可能您的 Application_Error 方法签名在某处不正确。我发布了一个例子。
    • 不,方法签名相同。我试过你的代码。但是控件不会到达 Application_Error 方法。我什至将 customErrors 模式的值从 remoteOnly 更改为 on,但仍然没有变化。我的意思是我被定向到 Errors.aspx 页面,但 Application_Error 没有被触发。
    • @Nachiket 我已经更新了我的答案,看看它是否适合你。
    • 嗨@Ephraim 我的代码中没有这个方法。这是我的代码的链接。如果您可以通过代码,将更容易识别错误。 [链接]drive.google.com/…
    【解决方案3】:

    如果您在调试时有&lt;customErrors mode="Off" /&gt;,代码将不会到达Application_Error 事件,因为异常会立即显示在浏览器中。

    如果你想在调试时到达 Application_Error,你想启用自定义错误 -

    <customErrors mode="On" defaultRedirect="~/Error.aspx" />
    

    【讨论】:

    • 嗨@Win,我试过了。但是控件永远不会到达 Application_Error 方法。虽然我确实被重定向到 Errors.aspx 页面
    • 是的,那么 Application_Error 到底是什么
    猜你喜欢
    • 2011-06-30
    • 2011-04-12
    • 1970-01-01
    • 2011-10-09
    • 2011-09-24
    • 2011-11-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    相关资源
    最近更新 更多