Изучив исходный код фреймворка, я могу объяснить, почему 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
невидимый член текущего контекста, мы увидим:
Это означает, что поток запроса не будет прерван, и поэтому код после Response.Redirect()
будет выполняться независимо от того, установлено вы endResponse
или нет.
Если мы установим точку останова внутри события Page_Load()
страницы ASPX, мы увидим что-то другое:
Невидимый элемент текущего контекста 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