繁体   English   中英

为什么我的ASP.NET MVC应用程序为单个会话多次触发Session_Start?

[英]Why does my ASP.NET MVC application fire Session_Start multiple times for a single session?

我们有一个MVC.NET应用程序,在重新启动时会遇到致命错误。 在Session_Start事件处理程序中,我们将会话ID添加到字典中。 在Session_End处理程序中,我们将其删除。 请考虑以下请求顺序:

取得home.mvc
<应用程序重启>
获取main.css
获取banner.jpg
获取somedata.mvc
...

由于构建应用程序的方式不同,如果在浏览器窗口中打开应用程序时进行重建,则这种序列会经常发生。 除了我在生产环境中也看到它之外,这并不是什么可怕的事情。 例如,当您编辑web.config时,它将发生(尽管很少)。

重新启动后的请求全部归因于主页中的链接或来自JavaScript的AJAX调用。

我观察到的是.NET并行处理前5个请求。 每个此类请求都会导致其触发Session_Start事件。 短暂的时间后,它将触发Session_End事件3次。 为了清楚起见,每个Session_Start都对应于完全相同的会话。 它们都具有相同的会话ID,并且所有会话状态对象的IsNewSession属性为true。 同样,Session_End事件对应于被终止的会话。 会话以及会话状态中存储的所有数据都会保留。

我需要防止它多次触发Session_Start或弄清楚如何知道Session_End何时并不真正意味着会话已结束。

事实证明,这个问题的答案是相当直截了当的,尽管这种行为确实令人困惑。

通常,MVC将所有请求同步到应用程序的会话状态锁上的应用程序(因为MVC的http模块被标记为需要会话状态)。 在我的情况下,应用程序在提供主页后重新启动。 因此,当与主页相关的请求进入时,该会话标识还没有会话状态,因此这些请求并行执行。

我看到5个并行请求,因为我正在XP上开发,而IIS的桌面版本仅限于5个并发请求。 由于这些请求中的任何一个都不存在会话状态对象,因此每个请求都将创建一个新的会话状态对象并触发Session_Start。 其中四个请求转到MVC操作方法。 由于这些要求会话状态,因此.NET会在请求完成后尝试将创建的会话状态对象与后备存储进行同步。

只有第一次同步才能成功。 .NET只是丢弃三个额外的会话状态对象,并为每个对象触发Session_End。 .NET不会尝试将第五个会话状态对象与后备存储区同步,因为它是为异步http模块创建的,该异步http模块被标记为需要只读会话状态。

因此,修复程序包括两个部分:

(1)现在,在我的Session_Start处理程序中,检查会话状态对象是否为只读。 如果是,那么我将立即不做任何事情而返回。 .NET将不会触发相应的Session_End,因此我所做的任何事情都将无法正确清理。

(2)现在,我在字典中保留了引用计数。 每当Session_Start处理程序尝试添加会话ID时,我都会增加计数,而每次Session_End尝试删除会话ID时,我都会减少计数。 一旦计数达到0,就从字典中删除会话ID。

如果客户端向您发送已过期的值,则可以重新使用会话ID。 在此处阅读<sessionState>元素的regenerateExpiredSessionId属性并注意默认值为“ true”

您可能还会发现很有趣:

我在开发中的一个旧ASP.NET应用中遇到了这种情况-事实证明cookie的RequireSSL设置为True ...这当然意味着会话cookie不会由客户端(本地主机)保留/重新发出。 ,非SSL)-因此后续请求会创建新的会话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM