将最后一个错误传递给自定义错误重定向的最佳方法?
-
13-09-2019 - |
题
想知道您对此解决方案的看法,这是否是将错误消息传递到自定义页面的正确方法?
在 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 变量。
所以,感谢您的回复。
- 不要忘记清除自定义错误页面中的错误。这个很重要。此外,还会指示不向用户准确显示所有错误。也许采用某种用户友好的格式。并在日志文件中提供所有信息,或通过电子邮件或其他方式发送。
希望这有用。