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

Posted

技术标签:

【中文标题】如果当前的 ASP.NET 会话为空,我该怎么办?【英文标题】:What should I do if the current ASP.NET session is null? 【发布时间】:2010-11-25 20:24:02 【问题描述】:

在我的 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?

【问题讨论】:

ASP.NET WebApi 会有不同的行为,你可以在Accessing Session Using ASP.NET Web API查看它 【参考方案1】:

以下说法并不完全准确:

“所以,如果你从你的页面调用其他功能,包括静态类,你应该没问题”

我正在调用一个通过 HttpContext.Current.Session 引用会话的静态方法,它为空。但是,我使用 jQuery 通过 ajax 通过 web 服务方法调用该方法。

我发现here 可以通过方法上的简单属性来解决问题,或者使用 Web 服务会话对象:

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

[WebMethod(EnableSession = true)]

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

感谢 Matthew Cozier 的解决方案。

只是想我会加两分钱。

埃德

【讨论】:

感谢 Ed,会话在 webmethod 中显示为空 - 添加此修复它。 +1 好吧,当您调用 Web 服务时,您使用的请求不是页面请求,因此该语句仍然正确,IMO。 MSDN 文档here - the default value is false。像魅力一样工作。【参考方案2】:

在我的情况下,ASP.NET State Service 已停止。将Startup type更改为Automatic并首次手动启动服务即可解决问题。

【讨论】:

【参考方案3】:

如果您的 Session 实例为 null 并且您在 'ashx' 文件中,只需实现 'IRequiresSessionState' 接口。

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

public class MyAshxClass : IHttpHandler, IRequiresSessionState

【讨论】:

非常感谢,我的登录课程中的会话为空。当我将此代码添加到我的 ashx 处理程序时,它也打开了我的课程的会话 我认为这很好地回答了这个问题。非常感谢。【参考方案4】:

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

如果您已禁用 SessionState http module,则完全禁用会话 如果您的代码在HttpApplication.AcquireRequestState 事件之前运行。 您的代码在IHttpHandler 中运行,它没有指定IRequiresSessionState 或IReadOnlySessionState 接口。

如果页面中只有代码,则不会遇到这种情况。我的大部分 ASP .NET 代码都使用 Session 而不重复检查 null。但是,如果您正在开发 IHttpModule 或者在 ASP .NET 的更严密的细节中遇到问题,则需要考虑这一点。

编辑

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

AcquireRequestState 在控制权交给您的主页之前运行。所以如果你从你的页面调用其他功能,包括静态类,你应该没问题。

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

此外,如果客户端禁用了 cookie,Session 对象仍然可用 - 但在下一次请求时,用户将返回一个新的空 Session。这是因为如果客户端还没有 Session 状态包,他会得到一个。如果客户端不传输会话cookie,我们无法识别客户端是否相同,因此将一次又一次地为他提供新的会话。

【讨论】:

只是我今天发现的一个快速更新。页面构造函数上的会话不可用!仅在 Init 事件或之后。 我刚遇到一个 HttpContext.Current.Session == null 是母版页的 Page_Load 事件调用的代码。显然,这可以发生在页面的上下文中。如果我检查 HttpContext.Current 对象,它的大部分成员都已初始化,但 CurrentNotification 和 IsPostNotification 会引发错误:System.PlatformNotSupportedException。不管是什么原因,这个问题在生产中并没有发生,它已经运行了多年。平台为 Windows Server 2003 R2 SP2,应用程序具有目标框架 .Net 3.5,并在启用会话状态的 IIS 中运行。 我还发现,当 IIS 为磁盘上存在的资源文件(例如样式表)提供直接请求时,HttpContext.Current.Session 在“Application_AcquireRequestState”中的代码可能为空。然而,对页面本身的请求确实使会话对象可用于那里的代码。这至少在 MVC.NET 4 下。 我认为如果您在输出缓存的 MVC 操作中,它也可能为 null。【参考方案5】:

ASP.NET Technical Articles

总结:在 ASP.NET 中,每个网页 派生自 System.Web.UI.Page 班级。 Page 类聚合一个 HttpSession 对象的实例 会话数据。 Page 类公开 不同的事件和方法 定制。特别是, OnInit 方法用于设置 初始化 Page 对象的状态。 如果请求没有 Session cookie,一个新的Session cookie 将发给请求者。

编辑:

Session: A Concept for Beginners

摘要:会话是在用户创建时创建的 向服务器发送第一个请求 对于 Web 应用程序中的任何页面, 应用程序创建会话 并将会话 ID 发送回 用户得到响应并被存储 在客户端机器上作为一个小 曲奇饼。所以理想的“机器 已禁用 cookie、会话 信息不会被存储”。

【讨论】:

以上是关于如果当前的 ASP.NET 会话为空,我该怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net 会话在 ashx 文件中为空

Asp.Net MVC 2中会话超时时的确认

ASP.NET 中的 REST WCF 服务和会话

asp.net c# MVC:没有 ViewState 我该如何生活?

ASP.NET CORE 2.2 WEB APP中的会话过期问题

Application Insights - ASP.NET Core - Session_Id 为空