在ASP.NET会话期间,在哪里存储自定义“用户”对象的最佳场所?
-
02-10-2019 - |
题
我有一个ASP.NET应用程序,需要在会话中记住有关用户(以及他们来自哪些公司)的一些信息。
我想这是几乎任何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
这节省了DB的旅行,但是如果用户对象复杂并且网站有许多并发用户,我会担心使用的内存。
我最近继承了一个在主页上使用公共属性的应用程序,例如:
Master.theUser = currentUser; // store at login
User currentUser = Master.theUser; // retrieve on some other page
这节省了演员阵容,我认为对我来说更易读,但我不知道表现更好还是更糟。它在getter中也具有一定的逻辑,如果私人值为null,则尝试从会话变量获取它,尽管我不确定是否从未使用过(或使用过) 每一个 得到!)或什么。
我的最新想法是使用我的页面课。我有一个从标准系统派生的自定义页面类。web.ui.pagebase类。它包括当前使用者作为公共属性之类的对象。这似乎还可以。我更喜欢它。
但是我真的不知道封面上发生了什么。谁能对哪种方法更好,为什么?
也欢迎这样做的其他建议。
更新:我已经完成了一些检查使用trace.axd and trace.write,看来MasterPage版本和自定义页面类版本“记住”页面之间的值。 “获取”方法具有一系列代码,该行检查用户属性是否为null,如果是的,则从会话变量中读取它。当页面首次在给定页面上访问属性(master.user或派生类的this.user)时,就会发生这种情况,然后后续请求可以获取值(无需转到会话变量)。
解决方案 3
因此,到目前为止,最好的解决方案看起来像这样:
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;
它将在您第一次使用时达到会话,但是在特定页面响应上的后续用途将更快。
现在,各个类别和代码范围内的代码看起来很整洁,因为每次使用时,我都不需要从会话中阅读和投射我的用户对象(以及公司对象等)。
其他提示
会议是为此目的而设计的。它存储了用户“会话”一生中相关的数据,我认为该数据是20分钟或用户关闭浏览器。如果您担心用户对象的大小,则可以存储ID,然后从DB中检索对象,但是您必须权衡DB往返的权衡。但是,我认为这通常不关心会话,因为它没有像ViewState那样发送给客户。您还可以使用像Culious Geek的示例这样的属性来公开此会话值,但使用会话对象而不是ViewState对象。
将主页上的属性设置为无法正常工作,因为这只是当前实例化类的成员,该类别在每个请求结束时收集垃圾,因此您在下一个请求中不会有它。
这是ASP.NET中的国家管理摘要:http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx
我同意你的看法 latest
主意。让公共页面基类公开类型的公共财产 user
. 。该属性应从/写入/写入会话密钥。我们还拥有另一个名为GOBACKPAGE的属性,该属性将上一页的URL存储在当前页面的视角中。
public string GoBackPage
{
get
{
return this.ViewState["__PrevPage"].ToString();
}
set
{
this.ViewState["__PrevPage"] = value;
}
}
您仍然可以超越这个 仅存储用户ID在View-State中 并在公共页面基类中公开属性,该属性将从视图状态读取用户ID并返回用户对象。