当一个类实例化,存储该实例由用户

问题描述:

我必须做下面的事情,当一个类被实例化我需要存储该实例的用户。由于我在asp.net工作,我想知道是否应该使用asp.net提供的一些方式来在用户请求之间保存数据。 (缓存不能是因为数据需要持久化和应用程序状态不能,因为它需要特定于用户),或者如果我应该寻找一种方法在类中存储该信息。并且需要坚持下去,直到我以编程方式说出如此当一个类实例化,存储该实例由用户

会话是存储特定用户数据的理想场所。

让我们假设这个答案,你需要在整个用户会话中持久化的类被称为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

您必须将其放入会自动管理的Session对象中。

+0

#我从来没有使用Session对象从类内部调用它,可以做到吗?我得到“会话名称未定义” #我应该担心这个吗? “Session对象是存储用户数据的效率较低的方法之一,因为即使在用户停止使用应用程序之后,它仍被保存在内存中一段时间​​。” – Pablo 2010-02-15 12:56:15

+0

顺便说一句,数据需要保持,直到我编程式说如此 – Pablo 2010-02-17 13:34:45