Что вызывает «Состояние сеанса создало идентификатор сеанса, но не может сохранить его, потому что ответ уже был сброшен приложением». - PullRequest
72 голосов
/ 25 мая 2009

Я периодически получаю эту ошибку.

Я нашел эту ссылку, которая довольно хорошо суммирует то, что мне удалось найти в Google: http://www.wacdesigns.com/2009/02/03/session-state-has-created-a-session-id-but-cannot-save-it-because-the-response-was-already-flushed-by-the-application/

По сути, это говорит о том, что вы можете попытаться установить параметр веб-конфигурации DisplayWhenNewSession или попытаться запустить состояние сеанса, получив Session.SessionID в Session_OnStart.

Но разве кто-нибудь:

а) есть объяснение этому

или даже лучше, б) иметь проверенное и исправленное исправление

Я понимаю, что не могу сбросить ответ после выполнения каких-либо действий, которые могут повлиять на заголовок ответа http. Если бы я сделал это, это вызвало бы ошибку каждый раз , но это периодически. SessionID, безусловно, должен автоматически создаваться ASP.NET в начале ответа страницы, прежде чем что-либо на странице ASPX или в Page_Load (именно там вызываются все мои сбросы).

Обновление: Размышляя, я понимаю, что это происходит при потоковой передаче файла в браузер. Большинство браузеров на самом деле являются поисковыми роботами. Я могу воссоздать эту ошибку, начав загрузку, а затем закрыв браузер, поэтому, вероятно, браузеры не ждут завершения загрузки, прежде чем отменить операцию загрузки. Я также видел это на других обычных страницах, но в 99% случаев это страницы загрузки.

Ответы [ 5 ]

76 голосов
/ 27 декабря 2009

У меня есть!

В файле global.asax вы делаете это:

void Session_Start(object sender, EventArgs e) 
{
    // Code that runs when a new session is started
    string sessionId = Session.SessionID;
}

Так просто. Это работает!

19 голосов
/ 16 марта 2010

Эта ошибка появляется, когда:

  • Запуск приложения

  • Вы используете Global.asax, даже если вы что-то делаете в событиях Session_Start / End или нет

  • Ваше приложение вызывает сброс ответа слишком рано

  • Вы не используете сессию до сброса

Он вызывается состоянием сеанса при попытке сохранить идентификатор сеанса при выпуске:

System.Web.SessionState.SessionIDManager.SaveSessionID(HttpContext context, String id, Boolean& redirected, Boolean& cookieAdded)
System.Web.SessionState.SessionStateModule.CreateSessionId()
System.Web.SessionState.SessionStateModule.DelayedGetSessionId()
System.Web.SessionState.SessionStateModule.ReleaseStateGetSessionID()
System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs)
System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Я полагаю, что наличие Global.asax приводит к тому, что идентификатор сеанса сохраняется при выпуске с помощью SessionStateModule (поздно?), Даже если сеанс не использовался вместо HttpSessionState при вызове SessionID.

Это причина, по которой string sessionId = Session.SessionID; хитрость позволяет избежать проблемы.

Полагаю, он появляется только при запуске приложения из-за поведения инициализации.

Решения / хитрости :

  • Избегайте очистки в Page_Load, как уже было сказано

  • Деактивировать состояние сеанса на странице (EnableSessionState)

  • Используйте трюк SessionID перед сбросом

  • Используйте Response.End () вместо .Flush (), если вам не нужны ошибки, которые могут возникнуть после сброса

6 голосов
/ 25 мая 2009

Я полагаю, что проблема здесь может заключаться именно в том, что вы что-то делаете для вывода страницы во время Page_Load, что, согласно Обзору жизненного цикла страницы ASP.NET , задолго до стадии рендеринга.

Убедитесь, что вы никогда не будете делать ничего, что могло бы вызвать вывод страницы, пока не пройдете этап PreRender.

3 голосов
/ 15 октября 2009

Просто столкнувшись с этой проблемой, я решил поделиться своими выводами.

Параметр web.config DisplayWhenNewSession не имеет значения, поскольку он применяется только к одному конкретному пользовательскому элементу управления в Codeplex (извините, я потерял ссылку).

Другое предложение, кажется, работает, инициализируя SessionId рано. Я копался в коде с помощью Reflector и не мог понять, как это предотвратило ошибку здесь, но это, безусловно, сработало для нас!

Как и большинство людей, которые, похоже, сталкиваются с этой ошибкой, мы явно не вызываем Response.Flush () нигде в приложении. Для записи мы также используем MVC.

0 голосов
/ 22 октября 2014

Я признаю, что это очень старая проблема, но я нашел другую причину ошибки, которая может относиться к другим. Если вы используете MVC (я использовал MVC 4 с .Net 4.0), и вы установили страницы не буферизировать с помощью элемента web.config

<pages buffer="false">    

Тогда, если в вашем коде вы пытаетесь вставить данные в объект сеанса, возможно, вы рискуете получить эту ошибку, если страница начала рендеринг перед вашим дочерним представлением или действием, выполняющим доступ к состоянию сеанса.

В таких случаях вы можете исправить ошибку, изменив вышеуказанную настройку буфера на true. Также можно переместить код доступа к сеансу в главное представление, а не в дочернее действие / дочернее представление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...