asp.net response.redirect в session_start не работает - PullRequest
5 голосов
/ 17 мая 2011

У меня есть простой 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(), где я исходил из предположения, что перенаправление является точкой выхода.

Я также пытался установить endResponse в перегруженном методе Response.Redirect(url, endResponse) как true или false, но это тоже не работает.

Ответы [ 3 ]

10 голосов
/ 17 мая 2011

Изучив исходный код фреймворка, я могу объяснить, почему 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 истинно, вызывается 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 невидимый член текущего контекста, мы увидим:

enter image description here

Это означает, что поток запроса не будет прерван, и поэтому код после Response.Redirect() будет выполняться независимо от того, установлено вы endResponse или нет.

Если мы установим точку останова внутри события Page_Load() страницы ASPX, мы увидим что-то другое:

enter image description here

Невидимый элемент текущего контекста IsInCancellablePeriod имеет значение true, поэтому будет вызван Thread.CurrentThread.Abort(), и после Response.Redirect().

больше не будет выполняться код.

Причина такой разницы в поведении, я подозреваю, связана с защитой целостности вашего состояния сеанса:

Не перенаправлять после установки переменной Session (или делать это правильно)

Если вам нужно предотвратить выполнение кода после Response.Redirect() в 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
0 голосов
/ 21 июня 2018

Да, .Redirect не прерывает поток, как в других senarios, но вы все равно можете вручную добавить HttpContext.Current.Response.End() после перенаправления, чтобы остановить обработку любой страницы.

0 голосов
/ 17 мая 2011

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

public void Redirect (
    string url,
    bool endResponse
)
  • url - Целевое местоположение.
  • endResponse - Указывает, следует ли прекратить выполнение текущей страницы.
...