2010-02-15 100 views
1

我必須做下面的事情,當一個類被實例化我需要存儲該實例的用戶。由於我在asp.net工作,我想知道是否應該使用asp.net提供的一些方式來在用戶請求之間保存數據。 (緩存不能是因爲數據需要持久化和應用程序狀態不能,因爲它需要特定於用戶),或者如果我應該尋找一種方法在類中存儲該信息。並且需要堅持下去,直到我以編程方式說出如此當一個類實例化,存儲該實例由用戶

回答

7

會話是存儲特定用戶數據的理想場所。

讓我們假設這個答案,你需要在整個用戶會話中持久化的類被稱爲UserInfo。的第一件事就是確保它被標記成,因此,它可以存儲在會話:

/// <summary> 
/// My custom class stored per user in Session. Marked as Serializable. 
/// </summary> 
[Serializable()] 
public class UserInfo 
{ 
    public string SimpleProperty 
    { get; set;} 
} 

從ASP.NET應用程序的App_Code文件夾中的代碼隱藏或類,可以直接呼叫會話:

//creating the user info as needed: 
UserInfo currentUserInfo = new UserInfo(); 

//storing the user info instance:  
Session["UserInfo"] = currentUserInfo; 

//getting the user info as needed: 
UserInfo currentUserInfo = (UserInfo)Session["UserInfo"]; 

如果在類庫/外部組件是應用程序的一部分,由ASP.NET網站/應用程序所引用,您可以通過訪問HttpContext.Current.Session會話。您的代碼,否則將是非常相似:

//creating the user info as needed: 
UserInfo currentUserInfo = new UserInfo(); 

//storing the user info:  
HttpContext.Current.Session["UserInfo"] = currentUserInfo; 

//getting the user info as needed: 
UserInfo currentUserInfo = (UserInfo)HttpContext.Current.Session["UserInfo"]; 

當編碼您類庫,它的建議,以確保HttpContext.Current不爲空,試圖訪問它之前和Session,因爲在某些情況下也可能是零。

以上所有應符合您的需求。按設計的會話範圍在用戶/會話級別,因此您可以在代碼中使用相同的會話密鑰。不需要其他特殊要求來保護類實例免受其他用戶/會話的影響。您提到的Cache對象不是正確的路,因爲它是應用程序範圍廣泛的,並且需要您實現自己的用戶級範圍以確保UserInfo實例不會在不同會話間意外共享。

最後一個建議 - 你甚至可以創建一個靜態實用程序/助手類,它可以根據需要訪問這些信息,這樣你的代碼就不需要繼續處理Session對象。簡單的例子:

public static class UserInfoManager 
{ 
    /// <summary> 
    /// Gets or sets the session-scoped user info when needed. 
    /// </summary> 
    public static UserInfo UserInformation 
    { 
     get 
     { 
      if(HttpContext.Current != null) 
       return (UserInfo)HttpContext.Current.Session["UserInfo"]; 

      return null; 
     } 
     set 
     { 
      HttpContext.Current.Session["UserInfo"] = value; 
     } 
    } 
} 

使用上述靜態類,你現在可以輕鬆地訪問類的實例,使用UserInfoManager.UserInformation

我希望這有助於。

編輯:

一個進一步的建議。在我們的應用程序中,當我們必須像您一樣爲每個用戶存儲一個類實例時,我們創建一個基類Page類,該類允許通過屬性直接訪問類實例。這也可以幫助你保持精緻的東西:

/// <summary> 
/// Base page class, which all pages in our site will inherit from 
/// </summary> 
public class MyBasePage : System.Web.UI.Page 
{ 
    /// <summary> 
    /// Gets or sets the session-scoped user info when needed. 
    /// </summary> 
    protected UserInfo UserInformation 
    { 
     get 
     { 
      if(HttpContext.Current != null) 
       return (UserInfo)HttpContext.Current.Session["UserInfo"]; 

      return null; 
     } 
     set 
     { 
      HttpContext.Current.Session["UserInfo"] = value; 
     } 
    } 
} 

然後在每個代碼後面的asp。網站或網頁應用程序:

/// <summary> 
/// Code-behind class for a page in my site 
/// </summary> 
public partial class SomePage : MyBasePage 
{ 
    public void Page_Load(object sender, EventArgs e) 
    { 
     //access the user info as needed 
     this.UserInformation.SimplyProperty = "something"; 
    } 
} 

正如您所看到的,現在只需要很少的代碼即可訪問類實例。

+0

TY。它看起來像你會得到100代表。但我會等待,看看是否有其他人回覆,並讓選票決定誰得到它:) – Pablo 2010-02-19 15:30:44

+0

NP。聽起來很公平.. – 2010-02-19 19:18:25

1

您必須將其放入會自動管理的Session對象中。

+0

#我從來沒有使用Session對象從類內部調用它,可以做到嗎?我得到「會話名稱未定義」 #我應該擔心這個嗎? 「Session對象是存儲用戶數據的效率較低的方法之一,因爲即使在用戶停止使用應用程序之後,它仍被保存在內存中一段時間​​。」 – Pablo 2010-02-15 12:56:15

+0

順便說一句,數據需要保持,直到我編程式說如此 – Pablo 2010-02-17 13:34:45