我遇到了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
我已成功写入会话并重新读取我的价值。
我认为这可能是由于以下三点之一:
[SessionState(SessionStateBehavior.ReadOnly)]
被破坏/忽略。[SessionState]
被覆盖。SessionStateBehavior.ReadOnly
实际上表示某种脏/乐观访问。任何人都可以确认吗?
我怀疑最后一个是真的,基于custom session provider documentation - 如果是,那么实现如何工作?写入“只读”会话是否存在并发错误(即最后写入获胜)或是否存在损坏会话和破坏异常的风险?
更新
看起来这是设计的(来自Microsoft's docs):
请注意,即使EnableSessionState属性标记为 ReadOnly,同一个应用程序中的其他ASP.NET页面也许能够 写入会话存储,因此请求只读会话数据 来自商店可能仍然会等待释放锁定的数据。
看起来上面的第二个选项实际上是这样 - 会话被锁定,模式变为可写。
答案 0 :(得分:10)
〜/ Sample / SetTest?value = foo
是的,它不会抛出任何错误,但它也不会在请求结束时保持会话。根据设计,在请求生命周期的最后,您写入会话的任何内容都会更新(仅当会话可写时)。
在我的测试中〜/ Sample / Test什么都不返回。
我认为当会话是只读时,他们应该在这里快速失败。
顺便提一下你的样本需要重写
string test = (string)this.Session["test"];