何时创建会话?

时间:2009-12-16 12:40:26

标签: c# asp.net session

在我的登录网页上(即用户点击的第一页)我有这种形式的代码:

public class MyPage : System.Web.UI.Page {
  private MyClass _obj = new MyClass();
  ...

MyClass有构造函数:

public MyClass() {
  var sess = HttpContext.Current.Session; // no problem here
  sess["MyValue"] = 123; // throws null ref exception coz sess is null
}

正如我所评论的那样,对sess["MyValue"]的调用会引发空引用异常,因为HttpContext尚未创建会话对象。

那么何时开始访问Session对象是安全的?我不想放弃_obj的内联声明/初始化;这对我来说非常方便!我有哪些替代方案?

4 个答案:

答案 0 :(得分:14)

您应该能够在Page的OnInit事件中或之后访问会话,或PreInit如果您感到困扰,则可以访问会话。在那之前,你就死了。

答案 1 :(得分:4)

会话在Http Module管道的 aquireRequestState 事件中创建。我试图在下面详细解释这一切。

我们在Http Module管道中有以下事件:
(页面前生命周期)
1. BeginRequest
2. AuthenticateRequest
3.授权请求
4. ResolveRequestCache
5. AcquireRequestState
6. PreRequestHandlerExecute

帖子后生命周期
7. PostRequestHandlerExecute
8. ReleaseRequestState
9. UpdateRequestCache
10. EndRequest

现在,正如我们所知,页面生命周期中的第一个事件是 PreInit 。 您正尝试在 PreInit 事件之前创建对象 _obj 。在请求生命周期中,这个对象的创建过程和构造函数的执行是在ResolveRequestCache期间完成的,即;在 AcquireRequestState 事件之前(因为这是在类中直接创建的,而不是任何方法)。正如预期的那样,由于 AcquireRequestState 尚未执行,因此构造函数中的会话仍然不可用。

页面生命周期中的

PreInit 方法在 AcquireRequestState 之后调用,因此会话在那里可用。

<强>结论: 最早的会话操作可以在Http Modules中的 AcquireRequestState 之后的任何时间完成(如果您以编程方式拦截请求)或在 PreInit 方法中/之后。

答案 2 :(得分:2)

如果用户位于站点的第一页,则会话中没有对象。在分配之前,你一定要检查它。

if (Session["MyValue"] == null)
   Session.Add("MyValue", "");

Session["MyValue"] = "123";

您还可以将Global.asax文件添加到项目中。这是您可以处理Session_Start事件的地方。

答案 3 :(得分:1)

您可以查看http管道。 Rich Starhl有一个nice article.。在aquireRequestState事件期间创建/检索会话对象。如果您有HTTP模块在此事件之前拦截请求,则您的会话可能尚未初始化