如果当前ASP.NET会话为空,该怎么办?


125

在我的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永远不应为null。这个假设正确吗?如果它可以为null,是否表示我还应该在存储一些内容之前对其进行检查:

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?
}

ASP.NET WebApi将具有不同的行为,您可以在使用ASP.NET Web API访问会话时
TiagoGouvêa16年

Answers:


158

是的,Session对象可能为null,但仅在某些情况下,您很少会遇到以下情况:

如果页面中仅包含代码,则不会遇到此问题。我的大多数ASP .NET代码都使用Session而不反复检查null。但是,如果要开发IHttpModule还是要考虑ASP.NET的详细信息,则需要考虑一下。

编辑

回应评论:会话状态是否可用取决于是否已为请求运行AcquireRequestState事件。在这里,会话状态模块通过读取会话cookie并为您找到适当的会话变量集来进行工作。

AcquireRequestState在将控制权移交给您的Page之前运行。因此,如果您要从页面调用其他功能,包括静态类,那应该没问题。

如果您有一些类在启动期间执行初始化逻辑,例如在Application_Start事件上或通过使用静态构造函数,则Session状态可能不可用。归结为是否存在当前请求和AcquireRequestState是否已运行。

同样,如果客户端禁用了cookie,则Session对象仍然可用-但在下一个请求时,用户将返回一个新的空Session。这是因为如果客户端没有会话状态包,则该客户端将获得一个会话状态包。如果客户端不传输会话cookie,则我们无法将客户端标识为相同的客户端,因此将一次又一次地向他发送新会话。


6
我今天发现的快速更新。会话在页面构造函数上不可用!仅在Init事件中或之后。
努诺·阿加皮托

我刚遇到HttpContext.Current.Session == null是母版页的Page_Load事件调用的代码。显然,这可能发生在页面上下文中。如果我检查HttpContext.Current对象,则将大多数成员初始化,但是CurrentNotification和IsPostNotification会引发错误:{System.PlatformNotSupportedException}。不管是什么原因,这个问题在已经运行了多年的生产中都没有发生过。该平台是Windows Server 2003 R2 SP2,该应用程序具有目标框架.Net 3.5,并且在启用了会话状态的IIS中运行。
R. Schreurs

我还发现,当IIS为磁盘上存在的资源文件(例如样式表)提供直接请求时,HttpContext.Current.Session可以将其为null以便在Application_AcquireRequestState中进行编码。但是,对页面本身的请求的确使会话对象可用于在那里进行编码。至少在MVC.NET 4下。
ingredient_15939

我认为如果您在输出缓存的MVC动作中,也可能为null。
user2173353

40

以下陈述并不完全正确:

“因此,如果您要从页面调用其他功能(包括静态类),则应该没问题”

我正在调用通过HttpContext.Current.Session引用会话的静态方法,它为null。但是,我通过使用jQuery的ajax通过webservice方法调用该方法。

正如我在这里发现的那样您可以使用方法的简单属性来解决问题,或者使用Web服务会话对象:

但是,有一个技巧,为了在Web方法中访问会话状态,您必须像这样启用会话状态管理:

[WebMethod(EnableSession = true)]

通过指定EnableSession值,您现在将拥有一个托管会话。如果不指定此值,则将获得一个空的Session对象,并且在尝试访问该会话对象时很有可能会遇到null引用异常。

感谢Matthew Cozier提供的解决方案。

只是以为我会加我的两分钱。

埃德


1
感谢Ed,Session在网络方法中显示为null-对此进行了修复。+1
Fusi 2012年

1
好吧,当您调用Web服务时,使用的不是页面请求,而是IMO,因此该语句仍然正确。
driis 2012年

MSDN文档在此处 - the default value is false。奇迹般有效。
Benjineer'1

22

如果您的Session实例为null,并且您的文件位于“ ashx”文件中,则只需实现“ IRequiresSessionState”接口即可。

该接口没有任何成员,因此您只需要在类声明(C#)之后添加接口名称:

public class MyAshxClass : IHttpHandler, IRequiresSessionState

非常感谢,会话在我的登录类中为null。当我将此代码添加到我的ashx处理程序中时,它也打开了我的课程的会话
13年

我认为这很好地回答了这个问题。非常感谢。
萨钦·约瑟夫

2

ASP.NET技术文章

简介:在ASP.NET中,每个网页都派生自System.Web.UI.Page类。Page类为会话数据聚合HttpSession对象的实例。Page类提供了不同的事件和自定义方法。特别是,OnInit方法用于设置Page对象的初始化状态。如果请求中没有会话cookie,则会将新的会话cookie发送给请求者。

编辑:

会议:初学者的概念

简介:在用户向Web应用程序中的任何页面的服务器发送第一个请求时创建会话,该应用程序创建会话并将会话ID与响应发送回用户,并以小cookie的形式存储在客户端计算机中。因此,理想情况下,“已禁用Cookie的计算机将不会存储会话信息”。


2

就我而言ASP.NET State Service被制止了。改变Startup typeAutomatic和手动启动该服务首次解决了这个问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.