将最后一个错误传递给自定义错误重定向的最佳方法?

发布于 2024-07-26 22:05:07 字数 2022 浏览 16 评论 0原文

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

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

Was wondering what you thought of this solution, if this is right way to pass an error message to a custom page?

In web.config:

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

In 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>

In my 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;
    }
}

Of issue: I don't want to do a Server.Transfer from Global.asax because.. I don't know. Seemed clumsy to me. Want to be able to change customErrors to RemoteOnly. So have to save last exception somewhere, but can't be Session, so save to Cache but with some extra data (time and SessionID) since Cache is global and want to make sure not showing wrong error to someone.


I changed my code somewhat. Now it's just:

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

...and...

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;
    }
}

Note SessionID not there if anonymous user, and ex.Data.Add a key that's already there will cause error making me realize it's important to call ClearError

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

说不完的你爱 2024-08-02 22:05:07

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

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

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

I think that's a decent way to do it. It's not the way I do it, but my code is too lengthy to post (and in VB.NET).

One thing I would change is the error page itself. Instead of displaying the error, consider adding a textbox to the error page as an optional field where the user can enter their email address and click a button to send the error report to you. Then when you receive the error report you can look at the problem and reply to them. It's a much more user friendly way to do it and it's worked out quite well for the sites I've done this on.

Along those lines, you might also want to gather form data, session data, and anything else of value and put that into the error report as well. This can make diagnosing problems much easier.

后来的我们 2024-08-02 22:05:07

我们做的事情可能适合你,也可能不适合你。 我们在数据库中进行了大量的日志记录。 当我们收到错误时,我们会将其记录下来并生成错误 ID。 我们重定向到带有错误 ID 的通用页面并在那里获取详细信息。

当然,当错误是“无法连接到数据库”时,这在表面上是平淡的,但这种情况不会经常发生;)

We do something that may or may not work for you. We do extensive logging in the DB. When we get an error, we log it and that produces an error ID. We redirect to the generic page with the error ID and get the details there.

of course this falls flat on its face when the error is 'cannot connect to DB' but that doesn't happen too often ;)

层林尽染 2024-08-02 22:05:07

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

看一下这个问题:

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

总结如下:

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

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

As cache is global this wouldn't be advisable, as you've said you could be displaying the wrong error to someone. I should also say that you shouldn't output the error message directly to end users for security reasons.

Have a look at this issue:

ASP.NET custom error page server GetLastError is null

To summarise put something like the following:

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

Rather than relying on ASP.NET to do the redirect using the settings in the CustomErrors section.

你怎么敢 2024-08-02 22:05:07

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

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

I would have to agree with both n8wrl and Steve that a better approach would be to log errors in the database and then return just an Error ID to the user. They really don't need to see the technical details and it is possible that this will expose sensitive information.

In our case, we also pass in the user's ID (if available) and the page where the error occurred (Request.URL is still good when you get to the global Application_Error). This way, we can track down the error a bit easier. Note also that you don't have to use Global.asax with a script tag. If you create a Global.asax.cs file in your App_Code directory, you can just code your C# directly (this may depend on the project type, though).

我早已燃尽 2024-08-02 22:05:07
Server.ClearError();

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

Server.ClearError();

This line should be placed on Error.aspx.cs after displaying ErrorMessage I think.

如若梦似彩虹 2024-08-02 22:05:07

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

所以,感谢您的回复。

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

希望这有用。

I was in charge of creating a custom Error page. Everything was pretty simple:
in the web.config file I had:

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

and in Global.asax, in the Application_Error method:
some code...

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

In the custom error page "error.aspx": Server.ClearError();

I don't know exactly what was modified, but this didn't worked anymore. When the code reached the Server.Transfer method, an exception was always raised: Error executing child request for the page...

I looked at some solutions and finally found this one.
I modified my code, and now it seems to work:

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

and in the global.asax method:

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

It also worked with the Cache[""] code, but I prefered the Session variable.

So, thanks for the responses.

  • don't forget to clear the error in the custom error page. This is important. Also, it would be indicated to not show exactly all the error to the user. Maybe in a certain user friendly format. And give all the information in a log file, or send it via email or something else.

Hope this was usefull.

痴情 2024-08-02 22:05:07
GetLastError();

请记住“此方法仅在 .asp 文件将任何内容发送到客户端之前可用。” - 来自 MSDN 文档< /a>

GetLastError();

Keep in mind "This method is available only before the .asp file has sent any content to the client." - from MSDN doc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文