Причина: «Состояние сеанса создало идентификатор сеанса, но не может его сохранить, потому что ответ уже был сброшен приложением».

80

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

Я нашел эту ссылку, которая довольно хорошо обобщает то, что мне удалось найти в Google: http://www.wacdesigns.com/2009/02/03/session-state-has-created-a-session-id-but- невозможно-сохранить-это-потому что-ответ-уже-был-сброшен-приложением /

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

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

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

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

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

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

Майк Нельсон
источник
1
У меня точно такая же проблема. Единственная причина, по которой я вообще это увидел, - это когда я поместил обработку исключений в Global.asax. Это очень прерывисто. Было бы здорово, если бы кто-нибудь знал ответ на этот вопрос!
Скотт Фергюсон,
6
Ссылка теперь не работает :-(
Casebash
Ссылка на машину Wayback: web.archive.org/web/20090208233145/http://www.wacdesigns.com/…
lorenzog

Ответы:

85

Я имею!

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

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

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

Эйтама
источник
Является ли это общедоступным / защищенным методом - поскольку он является частным, я думаю, он должен быть защищен. Полно ли образец, я полагаю, что то, что sessionId не сохраняется, в порядке - это запуск создания, что важно, верно?
Крис Кимптон,
Благодарю. Я думаю, что это в целом работает, поэтому я отмечу его как принятый ответ, хотя я не уверен на 100%. Кто-нибудь может прокомментировать, пожалуйста, если они найдут случай, когда это не работает? Благодарю.
Майк Нельсон
Я просто добавил этот метод в свой файл global.asax, и он избавился от моего сообщения об ошибке, которое было таким же, как и вопрос, большое спасибо, eitama!
vanhornRF
Это решило мою проблему (я принудительно промыл). Но знаете ли вы, почему это работает как решение?
Amicable
Этот ответ только что сэкономил мне много часов. Никогда бы не догадался. Спасибо!
HockeyJ 07
23

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

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

  • Вы используете 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

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

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

cjs
источник
Спасибо, я посмотрю на это сегодня вечером. Не знаете, почему это будет прерывисто?
Майк Нельсон
условный Response.Write () может быть в несоответствующем событии?
Джош Э,
3

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

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

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

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

Газ
источник
0

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

<pages buffer="false">    

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

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

Майк Тей
источник