2009-12-16 52 views
1

在我的登錄網頁(即第一個頁面,用戶點擊)我有這種形式的代碼:何時創建會話?

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尚未創建會話對象。

那麼,什麼時候開始訪問會話對象是安全的?我不想放棄_obj的內聯聲明/初始化;對我來說非常方便!我有什麼替代方案?

回答

13

如果您有此困擾,您應該能夠在頁面的OnInit事件中或之後訪問會話或PreInit。在此之前,你正在死亡。

+1

+1信息和LOL :) – 2009-12-16 12:46:55

1

你可以看看http管道。 Rich Starhl有一個nice article.。您的會話對象在aquireRequestState事件期間創建/檢索。如果您在此事件之前有HTTP模塊攔截請求,則您的會話可能尚未初始化

2

如果用戶位於站點的第一頁上,則會話中沒有任何對象。在分配給它之前,你一定要檢查這個值。

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

Session["MyValue"] = "123"; 

您還可以將Global.asax文件添加到項目中。這是您可以處理Session_Start事件的地方。

1

會話創建於aquireRequestState事件的Http模塊管道。我試圖在下面詳細解釋這件事。

我們有下面的HTTP模塊管道事件:
(預 - 頁生命週期)
1的BeginRequest
2. AuthenticateRequest
3的AuthorizeRequest
4. ResolveRequestCache
5. 的AcquireRequestState
6. PreRequestHandlerExecute

帖子 - 頁面生命週期
7 PostRequestHandlerExecute
8 ReleaseRequestState
9的UpdateRequestCache
10 EndRequest

現在,因爲我們都知道,在頁面生命週期的第一個事件是PreInit。 您正在嘗試在PreInit事件之前創建對象_obj。在請求生命週期中,創建對象和執行構造函數的過程在ResolveRequestCache期間完成,即: AcquireRequestState事件(因爲這是直接在類中創建的而不是任何方法)。正如所料,該會話仍然不會在構造函數中可用,因爲AcquireRequestState尚未執行。在頁面生命週期

PreInit方法被稱爲的AcquireRequestState之後,因此會話可用那裏。

結論: 最早會話操作可以在任何時間後的AcquireRequestState在HTTP模塊來完成(如果以編程方式截取了請求)或/後PreInit方法。