Я столкнулся с любопытным поведением 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
фактически указывает на какой-то грязный/оптимистический доступ.
Кто-нибудь может подтвердить?
Я подозреваю, что последнее верно, основываясь на пользовательской документации поставщика сеансов - если это так, то как работает реализация? Влияет ли запись на "только чтение" риск concurrency ошибок (т.е. Последних попыток записи) или же он рискует коррумпированными сеансами и нарушает исключения?
Обновление
Похоже, что это по дизайну (из Документов Microsoft):
Обратите внимание, что даже если атрибут EnableSessionState помечен как ReadOnly, другие страницы ASP.NET в одном приложении могут пишите в хранилище сеансов, поэтому запрос данных сеанса только для чтения из хранилища все равно может оказаться в ожидании освобождения заблокированных данных.
Похоже, что второй вариант выше - это то, что он на самом деле делает - сеанс заблокирован и режим изменился на записываемый.