【问题标题】:ReadOnly Session is writable只读会话是可写的
【发布时间】:2015-11-13 16:12:26
【问题描述】:

在out项目中,我们需要连续异步执行几个AJAX调用,所以下一个调用不必等待上一个返回。即使客户端异步发出调用,由于会话锁定,服务器也会按顺序处理它们。

由于我们不需要在这些调用中修改 Session,我们将 AJAX 调用的页面标记为 EnableSessionState="ReadOnly"via @Page 指令。它奏效了,调用变得真正异步,不再依赖于彼此的时间。但是我们发现 - 尽管被标记为只读,但在后端代码中 Session 是可写的。我们可以将值分配给 Session 并且这些值保持不变。这是设计的错误还是行为?

【问题讨论】:

  • 您使用的是什么会话状态模式(InProc、StateServer、SQLServer、自定义)?
  • @MichaelLiu 基本 InProc。有关系吗?只读不应该总是意味着只读吗?
  • StateServer 和 SQLServer 可能会像您期望的那样工作,但是如果您使用 InProc,则您有责任确保会话标记为只读时不会更新。 InProc(与 StateServer 和 SQLServer 不同)不会为每个请求制作会话状态的副本,因此 ASP.NET 无法检测或阻止对对象的更改。
  • @MichaelLiu 说得通。您能否将其发布为答案,以便我接受?

标签: asp.net session concurrency webforms session-variables


【解决方案1】:

我会说这种行为是进程内会话状态的“设计”陷阱(不幸的是,似乎没有很好的文档记录)。

进程外会话状态(状态服务器或 SQL Server)

在每个请求开始时,ASP.NET 将会话数据从外部存储加载并反序列化到内存中。每个请求都有自己的数据副本,因此对数据的更改不会影响同一会话中的其他并发请求。

如果 EnableSessionState 设置为 ReadOnly,那么在请求结束时,数据会被简单地丢弃,而不是序列化回外部存储。

进程中会话状态

不发生序列化或反序列化。相反,内存中只有一组会话数据,在会话期间存在。同一会话中的每个请求共享该组数据,并且对数据的更改立即对其他并发请求可见。

我想 ASP.NET 团队可以在 EnableSessionState 设置为 ReadOnly 时将 Session 设为只读:

this.Session["Customer"] = customer; // Why not throw InvalidOperationException?

但是 ASP.NET 仍然无法检测到对象本身的更改:

Customer customer = (Customer)this.Session["Customer"];
customer.Address = address; // ASP.NET can't detect this.

因此,如果您将 EnableSessionState 设置为 ReadOnly,您作为开发人员有责任避免更改会话数据。否则,您可能会引入多线程错误。

【讨论】:

    猜你喜欢
    • 2012-02-14
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 2017-01-04
    相关资源
    最近更新 更多