在我的 Web 应用程序中,我执行以下操作来读取会话变量:
if (HttpContext.Current.Session != null && HttpContext.Current.Session["MyVariable"] != null)
{
string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}
我明白为什么检查 HttpContext.Current.Session["MyVariable"] 为 null 的原因很重要(变量可能尚未存储在 Session 中,或者由于各种原因 Session 已被重置),但为什么我需要检查如果 HttpContext.Current.Session
为空?
我的理解是会话是由 ASP.NET 自动创建的,因此 HttpContext.Current.Session 永远不应为空。这个假设正确吗?如果它可以为空,是否意味着我也应该在存储一些东西之前检查它:
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
// What should be done in this case (if session is null)?
// Is it possible to force the session to be created if it doesn't exist?
}
是的,Session 对象可能为空,但仅在某些情况下,您很少会遇到:
如果您禁用了 SessionState http 模块,则完全禁用会话
如果您的代码在 HttpApplication.AcquireRequestState 事件之前运行。
您的代码在未指定 IRequiresSessionState 或 IReadOnlySessionState 接口的 IHttpHandler 中运行。
如果您只有页面中的代码,您将不会遇到这种情况。我的大部分 ASP .NET 代码都使用 Session 而不重复检查 null。但是,如果您正在开发 IHttpModule 或者在 ASP .NET 的更严密的细节中出现问题,则需要考虑这一点。
编辑
回答评论:会话状态是否可用取决于 AcquireRequestState 事件是否已针对请求运行。这是会话状态模块通过读取会话 cookie 并为您找到适当的会话变量集来工作的地方。
AcquireRequestState 在控制权交给您的主页之前运行。因此,如果您从您的页面调用其他功能,包括静态类,您应该没问题。
如果您有一些类在启动期间执行初始化逻辑,例如在 Application_Start 事件上或使用静态构造函数,则会话状态可能不可用。这一切都归结为是否存在当前请求并且 AcquireRequestState 已运行。
此外,如果客户端禁用了 cookie,则 Session 对象仍然可用 - 但在下一次请求时,用户将返回一个新的空 Session。这是因为如果客户端还没有 Session 状态包,他会得到一个。如果客户端不传输会话 cookie,我们无法识别客户端是否相同,因此将一次又一次地向他传递新会话。
以下陈述并不完全准确:
“所以,如果你从你的页面调用其他功能,包括静态类,你应该没问题”
我正在调用一个通过 HttpContext.Current.Session 引用会话的静态方法,它为空。但是,我通过使用 jQuery 的 ajax 通过 web 服务方法调用该方法。
正如我发现的 here,您可以使用方法上的简单属性来解决问题,或者使用 Web 服务会话对象:
但是有一个技巧,为了在 Web 方法中访问会话状态,您必须像这样启用会话状态管理: [WebMethod(EnableSession = true)] 通过指定 EnableSession 值,您现在将拥有一个托管会话来播放和。如果您不指定此值,您将获得一个空会话对象,并且在尝试访问会话对象时很可能会遇到空引用异常。
感谢 Matthew Cozier 的解决方案。
只是想我会加两分钱。
埃德
the default value is false
。奇迹般有效。
如果您的 Session 实例为 null 并且您在“ashx”文件中,则只需实现“IRequiresSessionState”接口。
该接口没有任何成员,因此您只需在类声明后添加接口名称(C#):
public class MyAshxClass : IHttpHandler, IRequiresSessionState
在我的情况下,ASP.NET State Service
已停止。将 Startup type
更改为 Automatic
并首次手动启动服务解决了该问题。
摘要:在 ASP.NET 中,每个网页都派生自 System.Web.UI.Page 类。 Page 类为会话数据聚合 HttpSession 对象的一个实例。 Page 类公开了用于自定义的不同事件和方法。特别是,OnInit 方法用于设置 Page 对象的初始化状态。如果请求没有 Session cookie,则会向请求者发出一个新的 Session cookie。
编辑:
Session: A Concept for Beginners
总结:当用户向服务器发送第一个请求以访问 Web 应用程序中的任何页面时,会创建会话,应用程序创建会话并将会话 ID 与响应一起发送回用户,并作为小 cookie 存储在客户端计算机中.因此,理想情况下,“禁用 cookie 的机器,不会存储会话信息”。
HttpContext.Current.Session
可能为空。然而,对页面本身的请求确实使会话对象可用于那里的代码。这至少在 MVC.NET 4 下。