1

我有一个 ASP.NET 应用程序,它需要在会话中跨页面记住有关用户(以及他们来自哪个公司)的一些信息。

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

过去,我在查询字符串参数中传递了一个 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 中也有一些逻辑,如果私有值为 null,它会尝试从 Session 变量中获取它,尽管我不确定是否从未使用过(或每次获取都使用过!?)或什么。

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

但我真的不知道幕后发生了什么。任何人都可以就哪种方法更好以及为什么提出意见?

也欢迎这样做的替代建议。

更新: 我已经对使用 trace.axd 和 Trace.Write 进行了一些检查,它看起来既不是母版页版本,也不是自定义页面类版本“记住”页面之间的值。“get”方法有一行代码检查 User 属性是否为空,如果是,则从会话变量中读取它。当页面在给定页面上第一次访问属性(Master.User 或派生类的 this.User)时会发生这种情况,然后后续请求可以获取该值(无需转到会话变量)。

4

3 回答 3

1

Session 正是为此目的而设计的。它存储用户“会话”生命周期的相关数据,我认为是 20 分钟或用户关闭浏览器。如果您关心您的用户对象的大小,您可以只存储 ID,然后从数据库中检索对象,但您必须权衡数据库往返的权衡。但是,我认为它通常与 Session 无关,因为它不像 ViewState 那样发送给客户端。您还可以使用 Curious Geek 示例中的属性公开此会话值,但使用 Session 对象而不是 ViewState 对象。

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

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

于 2010-07-06T15:50:40.843 回答
0

我同意你的latest想法。让公共页面基类公开类型为 your 的公共属性user。该属性应该从/向会话密钥读取/写入。我们还有另一个名为 GoBackPage 的属性,它将前一页的 URL 存储在当前页面的视图状态中。

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

        set
        {
            this.ViewState["__PrevPage"] = value;
        }
    }

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

于 2010-07-06T08:08:14.953 回答
0

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

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;

它会在你第一次使用时命中 Session,但随后在特定页面上的使用响应会更快。

各种类和代码隐藏中的代码现在看起来更整洁了,因为我不需要每次使用它时都从 Session 读取和转换我的 User 对象(和 Company 对象等)。

于 2012-02-23T04:07:34.527 回答