Session_Start 中的 Response.Redirect 不起作用

发布于 2024-11-07 09:47:19 字数 609 浏览 1 评论 0原文

我有一个简单的 Session_Start 代码,如下所示:

Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
    Dim sid = Session.SessionID
    Response.Redirect("~/Blog.aspx")
    dim dummy=4/0
End Sub

它没有按预期工作。通常在我的整个站点中,每当调用 Response.Redirect() 时,它也会终止代码执行。而在这里,即使页面最终重定向,dim dummy=4/0 行也会被执行。

这导致我在从 Session_Start() 调用的其他代码中出现问题,在这些代码中,我假设重定向是退出点。

我还尝试将 Response.Redirect(url, endResponse) 重载方法中的 endResponse 设置为 truefalse 但这也行不通。

I have a simple Session_Start code that looks like this:

Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
    Dim sid = Session.SessionID
    Response.Redirect("~/Blog.aspx")
    dim dummy=4/0
End Sub

It does not work as expected. Usually in my whole site, whenever Response.Redirect() is called, it also terminates the code execution. Whereas here, even if the page eventually redirects, the dim dummy=4/0 line is also executed.

This is causing me problems in other code called from Session_Start() where I built on the assumption that the redirect is an exit point.

I also tried setting endResponse in the Response.Redirect(url, endResponse) overloaded method as true or false but this doesn't work either.

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

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

发布评论

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

评论(3

红ご颜醉 2024-11-14 09:47:19

深入研究了框架源代码后,我可以解释为什么 Response.Redirect(url, true)Session_Start() 中被调用后继续执行代码,但在常规中则不然代码后面。

Response.Redirect() 最终调用 Redirect() 的内部重载方法:

internal void Redirect(string url, bool endResponse, bool permanent)
{
  // Miscellaneous goings on

  if (endResponse)
  {
    this.End();
  }
}

在此方法结束时,如果 endResponse 为 true,则< code>Response.End() 被调用。当我们查看 Response.End() 时,我们会看到以下代码:

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}

该方法检查当前上下文的 IsInCancellablePeriod 值的状态。该值是内部值,但我们可以在调试器中看到它:

如果我们在 Session_Start() 内设置断点并检查当前上下文的 IsInCancellablePeriod 不可见成员,我们会看到:

< img src="https://i.sstatic.net/MIZiH.png" alt="在此处输入图像描述">

这意味着请求的线程不会被中止,因此后面的代码无论您是否设置 endResponseResponse.Redirect() 都会执行。

如果我们在 ASPX 页面的 Page_Load() 事件中设置断点,我们会看到不同的结果:

enter image description这里

当前上下文的 IsInCancellablePeriod 不可见成员设置为 true,因此 Thread.CurrentThread.Abort() 将被调用,并且不会再有任何代码在Response.Redirect()之后执行。

我怀疑造成这种行为差异的原因是为了保护会话状态完整性:

设置会话变量后不要重定向(或正确执行)

如果您需要阻止代码在Session_Start() 中的 Response.Redirect() 那么您需要使用 If...Then...Else

If <some_condition_we_have_to_redirect_for> Then
    Response.Redirect("~/Blog.aspx")
Else
    // Normal session start code goes here
End If

Having had a dig into the framework source code I can explain why Response.Redirect(url, true) continues to execute code after being called in Session_Start() but not in regular code behind.

Response.Redirect() ultimately calls an internal overloaded method of Redirect():

internal void Redirect(string url, bool endResponse, bool permanent)
{
  // Miscellaneous goings on

  if (endResponse)
  {
    this.End();
  }
}

At the end of this method, if endResponse is true then Response.End() is called. When we look at Response.End() we see the following code:

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}

The method examines the state of the current context's IsInCancellablePeriod value. This value is internal but we can see it in our debugger:

If we set a breakpoint inside Session_Start() and examine the current context's IsInCancellablePeriod non-visible member we see:

enter image description here

This means that the request's thread won't be aborted and so the code after Response.Redirect() will execute, regardless of whether you set endResponse or not.

If we set a breakpoint inside an ASPX page's Page_Load() event we see something different:

enter image description here

The current context's IsInCancellablePeriod non-visible member is set to true and so Thread.CurrentThread.Abort() will be called and no more code will execute after the Response.Redirect().

The reason for this difference in behaviour is I suspect to do with protecting your session state integrity:

Don't redirect after setting a Session variable (or do it right)

If you need to prevent code from executing after a Response.Redirect() in Session_Start() then you'll need to use an If...Then...Else:

If <some_condition_we_have_to_redirect_for> Then
    Response.Redirect("~/Blog.aspx")
Else
    // Normal session start code goes here
End If
暖风昔人 2024-11-14 09:47:19

是的,.Redirect 不会像其他情况那样终止线程,但您仍然可以在重定向后手动添加 HttpContext.Current.Response.End() 以停止处理任何页面。

Yes, .Redirect won't terminate the thread like it does in other senarios, but you can still manually add a HttpContext.Current.Response.End() after the redirect to stop any page from processing.

夏尔 2024-11-14 09:47:19

http://msdn.microsoft.com/en -us/library/a8wa7sdt%28v=vs.80%29.aspx

public void Redirect (
    string url,
    bool endResponse
)
  • url - 目标位置。
  • endResponse - 指示当前页面的执行是否应终止。

http://msdn.microsoft.com/en-us/library/a8wa7sdt%28v=vs.80%29.aspx

public void Redirect (
    string url,
    bool endResponse
)
  • url - The target location.
  • endResponse - Indicates whether execution of the current page should terminate.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文