asp.net - "HttpContext.Current.Session"与 Global.asax "this.Session"

标签 asp.net session session-state global-asax

最近,在工作中为 ASP.NET 项目编写一些代码。我们需要一个跟踪实用程序来获取用户事件的基本指标(页面点击数等),我们将在 Session 中跟踪它们,然后通过Global.asax中的Session_End将数据保存到DB中.

我开始破解,初始代码运行良好,在每个页面加载时更新数据库。不过,我想删除每个请求上的数据库命中,并仅依靠 Session_End 来存储所有数据。

所有跟踪代码都封装在 Tracker 类中,包括本质上包装 session 变量的属性。

问题是,当我在 Session_End 方法中执行 Tracker.Log() 时,HttpContext.Current.Session跟踪器代码失败,并显示 NullReferenceException 。现在,这是有道理的,因为 HttpContext总是与当前请求相关,当然在Session_End中,没有请求。

我知道 Global.asax 有一个 Session 属性,它返回一个 HttpSessionState ,实际上似乎工作得很好(我最终注入(inject)了它进入跟踪器)..

但我很好奇,我到底如何才能从外部获取对 Global.asax 使用的 HttpSessionState 对象的相同引用 Global.asax 的 em>?

提前感谢大家,我很感谢您的意见。 :)

最佳答案

为了更好地回答原来的问题:

背景

每个页面请求都会启动一个新的 Session 对象,然后从 session 存储中对其进行扩充。为此,它使用客户端提供的 cookie 或特殊的路径构造(对于无 cookie session )。使用此 session 标识符,它会查询 session 存储并反序列化(这就是为什么除 InProc 之外的所有提供程序都需要可序列化)新的 session 对象。

对于 InProc 提供程序,仅向您提供存储在以 session 标识符为键的 HttpCache 中的引用。 这就是为什么 InProc 提供程序在 AppDomain 被回收时丢弃 session 状态(也是多个 Web 服务器无法共享 InProc session 状态的原因

这个新创建和膨胀的对象被固定在 Context.Items 集合中,以便它在请求期间可用。

您对 Session 对象所做的任何更改都会通过序列化(或者在 InProc 的情况下,HttpCache 条目)保留在对 session 存储的请求末尾已更新)。

由于 Session_End 在没有当前请求的情况下触发,因此 Session 对象会突然启动,没有可用的信息。如果使用 InProc session 状态,HttpCache 的过期会触发 Session_End 事件中的回调事件,因此 session 条目可用,但仍然是上次 session 条目的副本存储在HttpContext.Cache中。该值通过一个内部方法(称为 ProcessSpecialRequest)存储在 HttpApplication.Session 属性中,然后在该方法中可用。在所有其他情况下,它内部来自 HttpContext.Current.Session 值。

你的答案

由于 Session_End 总是针对空上下文触发,因此您应该始终在该事件中使用 this.Session 并将 HttpSessionState 对象传递给您的跟踪代码。在所有其他上下文中,从 HttpContext.Current.Session 获取然后传递到跟踪代码是完全可以的。但是,不要让跟踪代码到达 session 上下文。

我的回答

不要使用Session_End,除非您知道您正在使用的 session 存储支持Session_End,如果它返回,它就会支持来自 SetItemExpireCallback 的 >true。唯一能做到这一点的现成存储是 InProcSessionState 存储。可以编写一个 session 存储来执行此操作,但如果有多个服务器,谁来处理 Session_End 的问题就有点模糊了。

关于asp.net - "HttpContext.Current.Session"与 Global.asax "this.Session",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/464456/

相关文章:

asp.net - 访问所有事件客户端 session 集合?

c# - 如何在 Javascript 中访问 Sitecore 字段?

session - 如何恢复 Firefox 不是最后的 "Restore Previous Session"页面

asp.net - Azure 中的 session : client side sessions possible?

asp.net-mvc - 为什么ASP.NET MVC使用 session 状态?

c# - 使用 ASP.NET 网站进行持续部署?

asp.net - 如何检查 Amazon S3 存储桶中文件夹的子文件夹大小

c# - Azure 移动服务 Web Api 上的 SignalR CORS

asp.net - asp.net 中的 jQuery Ajax

php - 什么是好的和安全的 session 名称?