Я столкнулся с любопытным поведением ASP-сессий. Вы можете заставить контроллер находиться вне сеанса пользователя - я хочу сделать это так, чтобы несколько запросов могли выполняться одновременно, а использование сеанса заставляет их выполняться последовательно.
Отключение состояния сеанса работает как положено:
[SessionState(SessionStateBehavior.Disabled)]
public class SampleController : Controller
{
public ActionResult Test()
{
// Access to the session should be denied
object test = Session["test"];
return Content(test);
}
}
Переход к ~ / Sample / Test выдаст System.Web.HttpException
, как и ожидалось.
Однако сеансы только для чтения ведут себя немного странно:
[SessionState(SessionStateBehavior.ReadOnly)]
public class SampleController : Controller
{
public ActionResult Test()
{
// Read from the session should be fine
object test = Session["test"];
return Content(test);
}
public ActionResult SetTest(string value)
{
// Write to the session should fail
Session["test"] = value;
// Read it back from the session
object test = Session["test"];
return Content(test);
}
}
Так что теперь я ожидаю, что ~ / Sample / Test будет работать, и это работает. Странный бит в том, что набор тоже делает: я перехожу на ~ / Sample / SetTest? Value = foo , и он не выдает исключение, фактически он возвращает "foo". Если я вызываю ~ / Sample / SetTest? Value = bar , а затем ~ / Sample / Test , я получаю "bar", указывая на то, что сеанс был записан.
Таким образом, за SessionStateBehavior.ReadOnly
я успешно записал сеанс и прочитал свое значение обратно.
Я думаю, это может быть связано с одной из трех вещей:
- В MVC 3
[SessionState(SessionStateBehavior.ReadOnly)]
не работает / игнорируется.
-
[SessionState]
перезаписывается, когда сеанс записывается, и становится доступным для записи.
-
SessionStateBehavior.ReadOnly
фактически указывает на какой-то грязный / оптимистичный доступ.
Кто-нибудь может подтвердить?
Я подозреваю, что последний верен, основываясь на документации пользовательского поставщика сеансов - если это так, то как работает реализация? Риск записи в сеанс «только для чтения» риска параллелизма (т. Е. Выигрывает последняя запись) или риск повреждения сеансов и нарушения исключений?
Обновление
Похоже, что это дизайн (из документов Microsoft ):
Обратите внимание, что даже если атрибут EnableSessionState помечен как
ReadOnly, другие страницы ASP.NET в том же приложении могут
запись в хранилище сеансов, поэтому запрос данных сеанса только для чтения
из хранилища может остаться в ожидании освобождения заблокированных данных.
Похоже, что второй вариант выше - это то, что он на самом деле делает - сеанс заблокирован и режим изменен на доступный для записи.