session_start中的asp.net response.redirect不起作用

Yis*_*ski 5 asp.net session redirect response

我有一个简单的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
Run Code Online (Sandbox Code Playgroud)

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

这导致我在其他代码中出现问题Session_Start(),我建立在重定向是退出点的假设之上.

我也尝试endResponseResponse.Redirect(url, endResponse)重载方法中设置为truefalse但是这也不起作用.

Kev*_*Kev 11

深入研究了框架源代码,我可以解释为什么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();
  }
}
Run Code Online (Sandbox Code Playgroud)

在此方法结束时,如果endResponse为true则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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

在此输入图像描述

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

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

在此输入图像描述

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

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

设置Session变量后不要重定向(或者正确)

如果你需要阻止代码在Response.Redirect()in Session_Start()之后执行,那么你需要使用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
Run Code Online (Sandbox Code Playgroud)