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

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


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

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

有帮助吗?

解决方案

我认为这是做一个体面的方式。这不是我做的方式,但我的代码是过于冗长张贴(和VB.NET)。

有一件事我会改变是错误页面本身。相反,显示错误的,考虑添加一个文本框到错误页面作为可选字段,用户可以输入自己的电子邮件地址,然后点击一个按钮来将错误报告发送给您。然后,当您收到错误报告,你可以看看这个问题,并回答他们。这是做一个更加用户友好的方式和它的工作得非常好,因为我已经做到了这一点的网站上。

根据这些原则,你可能还需要收集表单数据,会话数据,和其他任何的价值,将其写入错误报告为好。这可以使诊断问题变得更加容易。

其他提示

我们做一些事情,可能会或可能不会为你工作。我们做大量的日志记录在数据库中。当我们得到一个错误,我们会记录,并产生一个错误ID。我们重定向到与错误ID通用页面,并获得详细信息那里。

当然当误差“无法连接到DB”,但这不会发生过于频繁,这属于平面在其表面上;)

由于缓存是全球性的,这将是不可取的,因为你说过你可能会显示不正确的错误的人。我还要说,你不应该直接输出错误信息到最终用户出于安全原因。

看一看这个问题:

ASP.NET自定义错误页服务器GetLastError函数为空

要总结放类似如下:

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

而不是依靠ASP.NET做在的customErrors部中的设置的重定向。

我想有两个n8wrl和史蒂夫同意,一个更好的方法是登录数据库的错误,然后只是一个错误ID返回给用户。他们真的不需要看到技术细节,这是可能的,这将暴露敏感信息。

在我们的例子中,我们还通过在用户的ID(如果可用)和发生错误的页面(Request.URL仍然是良好的,当你到了全球的Application_Error)。这样,我们可以跟踪误差容易一点。还需要注意的是,你不必使用Global.asax中使用的脚本标签。如果您在您的App_Code目录一个的Global.asax.cs文件,你可以直接编写你的C#(这可能取决于项目的类型,虽然)。

Server.ClearError();

此行应显示的ErrorMessage我认为后放在Error.aspx.cs。

我负责创建自定义错误页面。一切都很简单:在 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 变量。

所以,感谢您的回复。

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

希望这有用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top