2010-06-08 19 views
0

好吧,我有這個單身類的網絡類,它使用會話來維護狀態。我最初認爲我將不得不在每個「集合」上操作會話變量,以便在會話中更新新值。不過,我嘗試使用它,不知何故,它記住了狀態。即使會話未在屬性設置器中更新,此類Singleton類web類如何保持會話數據?

例如,如果一個頁面上運行此代碼:

UserContext.Current.User.FirstName = "Micah"; 

,並運行在不同的瀏覽器選項卡上的代碼,名字是正確顯示:

Response.Write(UserContext.Current.User.FirstName); 

誰能告訴我(證明)該數據如何在會話中持續存在?這裏是類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

public class UserContext 
{ 
    private UserContext() { } 

    public static UserContext Current 
    { 
    get 
    { 
     if (System.Web.HttpContext.Current.Session["UserContext"] == null) 
     { 
     UserContext uc = new UserContext(); 
     uc.User = new User(); 
     System.Web.HttpContext.Current.Session["UserContext"] = uc; 
     } 

     return (UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 
    } 
    } 

    private string HospitalField; 
    public string Hospital 
    { 
    get { return HospitalField; } 
    set 
    { 
     HospitalField = value; 
     ContractField = null; 
     ModelType = null; 
    } 
    } 

    private string ContractField; 
    public string Contract 
    { 
    get { return ContractField; } 
    set 
    { 
     ContractField = value; 
     ModelType = string.Empty; 
    } 
    } 

    private string ModelTypeField; 
    public string ModelType 
    { 
    get { return ModelTypeField; } 
    set { ModelTypeField = value; } 
    } 

    private User UserField; 
    public User User 
    { 
    get { return UserField; } 
    set { UserField = value; } 
    } 

    public void DoSomething() 
    { 
    } 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public string FirstName { get; set; } 
} 

我加入這一塊手錶,並可以看到會話變量肯定是被設置的地方:

(UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 

只要二傳手被稱爲會話變量被即時更新:

set 
    { 
     HospitalField = value; //<--- here 
     ContractField = null; 
     ModelType = null; 
    } 

回答

2

UserContext實例保存在會話這一行:

System.Web.HttpContext.Current.Session["UserContext"] = uc; 

這不是一個單身人士。靜態屬性UserContext將嘗試從Session中檢索實例,如果它找不到它,請創建一個新實例並將其存儲在Session中。

UPDATE

我可以看到會話VAR如何檢索,我的困惑是圍繞會議VAR是如何設置的。

要添加澄清以下Micah的評論:第一次訪問靜態Current屬性,創建一個新的UserContext實例,其User屬性填充一個新的User實例,並且UserContext實例存儲在會話中。後續對同一會話中的UserContext.Current(因此UserContext.Current.User)的訪問都訪問相同的實例。

如果還不清楚,我建議逐步使用調試器。

public static UserContext Current 
{ 
    get 
    { 
     // If Session does not yet contain a UserContext instance ... 
     if (System.Web.HttpContext.Current.Session["UserContext"] == null) 
     { 
      // ... then create and initialize a new UserContext instance ... 
      UserContext uc = new UserContext(); 
      uc.User = new User(); 
      // ... and store it in Session where it will be available for 
      // subsequent requests during the same session. 
      System.Web.HttpContext.Current.Session["UserContext"] = uc; 
     } 
     // By the time we get here, Session contains a UserContext instance, 
     // so return it. 
     return (UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 
    } 
} 
+0

我可以看到如何檢索會話變量,我的困惑是如何設置會話變量。當我運行UserContext.Current.User.FirstName =「Micah」;我沒有看到它被放回到會話var中的任何地方。會話設置的唯一時間是創建沒有數據的新實例。 – 2010-06-08 14:20:21

+0

我不確定你是否明白我在問什麼。只要代碼調用「HospitalField = value」;會議從無效到填充醫院名稱。在該行執行之前,會話變量中的所有字段均爲空。會議在哪裏設置? 代碼設置會話var的唯一地方是當它填充了一個帶有空字段的新對象時。 – 2010-06-09 03:24:01

+0

當您調用「UserContext.Current.Hospital = value;」時,首先調用獲取器UserContext.Current(並在Session中創建對象),然後調用「Hospital」設置器,此時該對象已創建在會議中。你是否嘗試過使用調試器?您可能需要更改您的VS Debug設置,以便它進入屬性以查看發生了什麼。 – Joe 2010-06-09 04:25:33

0

而且在不同的瀏覽器 標籤運行這段代碼,名字顯示正確 :

要保存它的會話。打開一個新標籤可以使用與其他標籤相同的會話信息(我不確定所有瀏覽器)。嘗試打開一個新的瀏覽器窗口(不只是一個標籤),看看會發生什麼。

+0

我使用新的瀏覽器窗口獲得相同的行爲。 – 2010-06-08 14:21:55

+0

我的問題是*如何在會話中保存。 – 2010-06-09 13:48:55

1

喬是對的。您的用途是:UserContext.Current.User.FirstName

在獲取器UserContext.Current中,您將獲取對位於asp.net中會話對象內部的一段內存的引用。使用任何setter都應該/會改變這個內存,如果你在調試器或後面的代碼行檢查session對象,你應該看到你用setter設置的相同數據。

+0

這很有道理。它作爲鑄造對象返回,因此可以設置強類型屬性。 – 2010-06-09 19:15:04