代码之家  ›  专栏  ›  技术社区  ›  MGOwen

在ASP.NET会话期间,存储自定义“用户”对象的最佳位置是哪里?

  •  1
  • MGOwen  · 技术社区  · 16 年前

    我想这是任何特定大小的ASP.NET应用程序的要求。这些年来我用了几种不同的方法。

    过去,我在querystring参数中传递了一个id,如下所示:

    site.com/page.aspx?usrid=1&companyid=2
    

    另一种常见的方法是将对象存储在会话变量中:

    Session["User"] = currentUser;              // store at login
    User currentUser = (User)Session["User"];   // retrieve on some other page
    

    这样就省去了对数据库的访问,但是如果用户对象很复杂并且站点有很多并发用户,我会担心内存的使用。

    我最近继承了一个在母版页上使用公共属性的应用程序,如下所示:

    Master.theUser = currentUser;         // store at login
    User currentUser = Master.theUser;    // retrieve on some other page
    

    这节省了演员阵容,我认为看起来更具可读性,但我不知道这是更好还是更差的表现明智。它在getter中也有一些逻辑,如果private值为null,它会尝试从Session变量中获取它,尽管我不确定它是否从未使用过(或使用过) 每一个 得到!?)或者什么。

    我的最新想法是使用我的页面类。我有一个从标准System.Web.UI.page基类派生的自定义页面类。它包括像CurrentUser这样的对象作为公共属性。这似乎行得通。我更喜欢它。

    更新: 我已经检查了use trace.axd和trace.Write,看起来母版页版本和自定义页类版本都没有“记住”页之间的值。“get”方法有一行代码,用于检查用户属性是否为null,如果为null,则从会话变量中读取该属性。当页面第一次访问给定页面上的属性(Master.User或派生类的This.User)时,会发生这种情况,随后的请求可以获取该值(而不必访问session变量)。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Dave Thieben    16 年前

    会议就是为了这个目的而设计的。它为用户的“会话”的生命周期存储相关数据,我认为这是20分钟或者用户关闭浏览器。如果您关心用户对象的大小,您可以只存储ID,然后从DB中检索对象,但是您必须权衡DB往返的利弊。但是,我不认为它通常与会话有关,因为它不像ViewState那样发送到客户端。您也可以使用一个属性公开这个session值,就像好奇的Geek的例子一样,但是使用session对象而不是ViewState对象。

    在母版页上设置属性将不起作用,因为它只是当前实例化类的一个成员,该类在每个请求结束时都会被垃圾收集,因此在下一个请求中不会有它。

    以下是ASP.NET中状态管理的摘要: http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx

        2
  •  0
  •   this. __curious_geek    16 年前

    我同意你的看法 latest 想法。让公共页基类公开您的类型的公共属性 user

        public string GoBackPage
        {
            get
            {
                return this.ViewState["__PrevPage"].ToString();
            }
    
            set
            {
                this.ViewState["__PrevPage"] = value;
            }
        }
    

    你仍然可以超越这一点 仅在视图状态下存储用户标识 并在公共页基类中公开一个属性,该属性将从视图状态读取UserId并返回User对象。

        3
  •  0
  •   MGOwen    14 年前

    到目前为止,最好的解决方案如下:

    public class MyPage : System.Web.UI.Page
    {
    
    
    private User user;
    public User User
    {
        get
        {                   
            if (user == null)
            {
            user = (User)HttpContext.Current.Session["CurrentUser"];    //check if session[CurrentUser] is null here and log them out if so?
            }
            return user;
        }
        set
        {
            user = value;
            HttpContext.Current.Session["CurrentUser"] = value;
        }
    }
    
    }
    

    然后在任何webpage.aspx.cs上,您可以执行以下操作:

    UsernameTextBox.Text = User.FullName;
    

    各种类和后面的代码现在看起来整洁多了,因为我不需要每次使用会话时都从会话中读取和转换我的用户对象(和公司对象等)。

    推荐文章