【问题标题】:Best way to pass last error to custom error redirect?将最后一个错误传递给自定义错误重定向的最佳方法?
【发布时间】:2010-11-10 18:21:51
【问题描述】:

想知道您对这个解决方案的看法,如果这是将错误消息传递到自定义页面的正确方法?

在 web.config 中:

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

在 Global.asax 中:

<script RunAt="server">
    void Application_Error(object sender, EventArgs e)
    {
    Exception ex = Server.GetLastError();
    if (ex != null && Session != null)
    {
        ex.Data.Add("ErrorTime", DateTime.Now);
        ex.Data.Add("ErrorSession", Session.SessionID);
        HttpContext.Current.Cache["LastError"] = ex;
    }
    }

</script>

在我的 Error.aspx.cs 中:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;

    if (HttpContext.Current.Cache["LastError"] != null)
    {
        Exception ex = (Exception)HttpContext.Current.Cache["LastError"];
        if (ex.Data["ErrorTime"] != null && ex.Data["ErrorSession"] != null)
            if ((DateTime)ex.Data["ErrorTime"] > DateTime.Now.AddSeconds(-30d) && ex.Data["ErrorSession"].ToString() == Session.SessionID)
                Label1.Text = ex.InnerException.Message;
    }
}

问题:我不想从 Global.asax 做一个 Server.Transfer 因为..我不知道。对我来说似乎很笨拙。希望能够将 customErrors 更改为 RemoteOnly。所以必须在某个地方保存最后一个异常,但不能是 Session,所以保存到 Cache 但带有一些额外的数据(时间和 SessionID),因为 Cache 是全局的,并且希望确保不会向某人显示错误的错误。


我稍微改变了我的代码。现在只是:

void Application_Error(object sender, EventArgs e)
{
    HttpContext.Current.Cache["LastError"] = Server.GetLastError().GetBaseException();
    Server.ClearError();
}

...和...

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;

    if (HttpContext.Current.Cache["LastError"] != null)
    {
        Exception ex = (Exception)HttpContext.Current.Cache["LastError"];
        if (ex != null)
            Label1.Text = ex.Message;
    }
}

如果匿名用户,请注意 SessionID 不存在,并且 ex.Data.Add 已经存在的密钥会导致错误,让我意识到调用 ClearError 很重要

【问题讨论】:

  • 郑重声明,对错误进行重定向的页面真的很烦人,因为它们让我很难将看到错误的 URL 发送给您,或者稍后重试。
  • 此外,Server.Transfer 不适用于某些部分页面回发 - 我们正在这样做,但是当从 UpdatePanel 中启动错误时它失败了

标签: asp.net caching custom-errors getlasterror


【解决方案1】:

由于缓存是全局的,因此不建议这样做,正如您所说的那样,您可能会向某人显示错误的错误。我还应该说,出于安全原因,您不应该将错误消息直接输出给最终用户。

看看这个问题:

ASP.NET custom error page server GetLastError is null

总结如下:

Server.Transfer(String.Concat("~/Error.aspx?message=", HttpUtility.UrlEncode(ex.InnerException.Message)))

而不是依赖 ASP.NET 使用 CustomErrors 部分中的设置进行重定向。

【讨论】:

  • +1 - 我同意您不应该向用户显示错误。正如我在回答中描述的那样,我们将其记录在数据库中。
【解决方案2】:

我们做的事情可能对您有用,也可能对您无效。我们在数据库中进行大量日志记录。当我们收到错误时,我们会记录它并生成错误 ID。我们重定向到带有错误 ID 的通用页面并在那里获取详细信息。

当然,当错误是“无法连接到数据库”时,这会一无所获,但这种情况不会经常发生;)

【讨论】:

  • +1 来自我 - 我的回答有点不同,但我们也使用数据库日志记录,所以我支持你。
【解决方案3】:

我认为这是一个不错的方法。这不是我这样做的方式,但我的代码太长而无法发布(以及在 VB.NET 中)。

我要改变的一件事是错误页面本身。不要显示错误,而是考虑将文本框添加到错误页面作为可选字段,用户可以在其中输入他们的电子邮件地址并单击按钮将错误报告发送给您。然后,当您收到错误报告时,您可以查看问题并回复他们。这是一种对用户更加友好的方式,并且对于我所做过的网站来说效果很好。

沿着这些思路,您可能还想收集表单数据、会话数据和其他任何有价值的东西,并将其也放入错误报告中。这样可以更轻松地诊断问题。

【讨论】:

  • +1 好答案 - 我喜欢给用户一点空间来发送电子邮件的想法。由于用户群的规模,我们不能真正做到这一点,但我们确实将所有内容都记录在数据库中。
  • 谢谢,对我们来说效果很好。在我们最大的网站上,我们有 50,000 多名用户完成了我们 15-20 页的在线申请。而我对这种技术的发现是,由于用户的期望和我自己的期望,它会产生一种紧迫感。它有一种激励我消除所有错误的方法。一旦我这样做了,我花在支持网站上的时间就会少得多,而花更多的时间来改进它。
  • 只是为了扩展这一点,我不能足够强调良好的错误报告是多么重要。当您收到大量将错误置于上下文中的详细信息时,它真的很有帮助。例如,如果您遍历每个表单键/值对并将其包含在错误报告中,那么您就知道用户在表单中输入了什么。
【解决方案4】:

我不得不同意 n8wrl 和 Steve 的观点,更好的方法是在数据库中记录错误,然后只向用户返回一个错误 ID。他们确实不需要查看技术细节,这可能会暴露敏感信息。

在我们的例子中,我们还传递了用户 ID(如果可用)和发生错误的页面(当您到达全局 Application_Error 时,Request.URL 仍然有效)。这样,我们可以更容易地追踪错误。另请注意,您不必将 Global.asax 与脚本标记一起使用。如果您在 App_Code 目录中创建 Global.asax.cs 文件,则可以直接编写 C# 代码(不过,这可能取决于项目类型)。

【讨论】:

    【解决方案5】:
    Server.ClearError();
    

    我认为在显示ErrorMessage之后,这一行应该放在Error.aspx.cs上。

    【讨论】:

    • 我相信这将防止错误在默认配置下被记录到 Windows 事件日志中。
    【解决方案6】:

    我负责创建自定义错误页面。一切都很简单: 在我拥有的 web.config 文件中:

    <customErrors mode="On">
    <error statusCode="404" redirect="~/error-pages/page-not-found.aspx?error=1"
    </customErrors>
    

    在 Global.asax 的 Application_Error 方法中: 一些代码...

    Server.Transfer("~/error-pages/error.aspx");
    

    在自定义错误页面“error.aspx”中:Server.ClearError();

    我不知道具体修改了什么,但这不再起作用了。当代码到达Server.Transfer方法时,总是抛出异常:Error execution child request for the page...

    我查看了一些解决方案,最后找到了这个。 我修改了我的代码,现在它似乎可以工作了:

    <customErrors mode="On" defaultRedirect="~/error-pages/error.aspx">
      <error statusCode="404" redirect="~/error-pages/page-not-found.aspx?error=1" />
    </customErrors>
    

    在 global.asax 方法中:

    Session["LastError"] = Server.GetLastError();
    

    它也适用于 Cache[""] 代码,但我更喜欢 Session 变量。

    所以,感谢您的回复。

    • 不要忘记在自定义错误页面中清除错误。这个很重要。此外,它会被指示不向用户显示所有错误。也许以某种用户友好的格式。并在日志文件中提供所有信息,或通过电子邮件或其他方式发送。

    希望这是有用的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-15
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      相关资源
      最近更新 更多