5

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

在 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。所以必须在某处保存最后一个异常,但不能是会话,所以保存到缓存但有一些额外的数据(时间和 SessionID),因为缓存是全局的,并且希望确保不会向某人显示错误的错误。


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

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 很重要

4

6 回答 6

7

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

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

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

于 2009-07-14T22:20:11.047 回答
1

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

看看这个问题:

ASP.NET 自定义错误页面服务器 GetLastError 为 null

总结如下:

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

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

于 2009-07-14T19:30:28.750 回答
1

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

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

于 2009-07-14T19:33:08.403 回答
1

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

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

于 2009-07-14T23:59:11.440 回答
0
Server.ClearError();

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

于 2009-10-29T11:35:46.000 回答
0

我负责创建自定义错误页面。一切都很简单:在 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 方法时,总是引发异常:执行页面的子请求时出错...

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

<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 变量。

所以,感谢您的回复。

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

希望这很有用。

于 2013-10-03T13:01:41.533 回答