即使会话没有在属性设置器中更新,这个类似 Singleton 的 web 类如何保持会话数据? [英] How does this Singleton-like web class persists session data, even though session is not updated in the property setters?
问题描述
好的,我有这个类似单例的 web 类,它使用会话来维护状态.我最初认为我将不得不在每个集合"上操作会话变量,以便在会话中更新新值.但是我尝试按原样使用它,不知何故,它记住了状态.
Ok, I've got this singleton-like web class which uses session to maintain state. I initially thought I was going to have to manipulate the session variables on each "set" so that the new values were updated in the session. However I tried using it as-is, and somehow, it remembers state.
例如,如果在一页上运行此代码:
For example, if run this code on one page:
UserContext.Current.User.FirstName = "Micah";
并在不同的浏览器选项卡中运行此代码,FirstName 显示正确:
And run this code in a different browser tab, FirstName is displayed correctly:
Response.Write(UserContext.Current.User.FirstName);
有人能告诉我(证明)这些数据是如何在会话中持久化的吗?这是课程:
Can someone tell me (prove) how this data is getting persisted in the session? Here is the class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class UserContext
{
private UserContext() { }
public static UserContext Current
{
get
{
if (System.Web.HttpContext.Current.Session["UserContext"] == null)
{
UserContext uc = new UserContext();
uc.User = new User();
System.Web.HttpContext.Current.Session["UserContext"] = uc;
}
return (UserContext)System.Web.HttpContext.Current.Session["UserContext"];
}
}
private string HospitalField;
public string Hospital
{
get { return HospitalField; }
set
{
HospitalField = value;
ContractField = null;
ModelType = null;
}
}
private string ContractField;
public string Contract
{
get { return ContractField; }
set
{
ContractField = value;
ModelType = string.Empty;
}
}
private string ModelTypeField;
public string ModelType
{
get { return ModelTypeField; }
set { ModelTypeField = value; }
}
private User UserField;
public User User
{
get { return UserField; }
set { UserField = value; }
}
public void DoSomething()
{
}
}
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
}
我将此添加到手表中,并且可以看到会话变量肯定被设置在某处:
I added this to a watch, and can see that the session variable is definitely being set somewhere:
(UserContext)System.Web.HttpContext.Current.Session["UserContext"];
只要 setter 被调用,会话变量就会立即更新:
As soon as a setter is called the Session var is immediately updated:
set
{
HospitalField = value; //<--- here
ContractField = null;
ModelType = null;
}
推荐答案
UserContext
instance 保存在 Session 中,下面一行:
The UserContext
instance is saved in Session with this line:
System.Web.HttpContext.Current.Session["UserContext"] = uc;
这不是单例.静态属性 UserContext
将尝试从 Session 检索一个实例,如果没有找到,则创建一个新实例并将其存储在 Session 中.
It's not a singleton. The static property UserContext
will attempt to retrieve a instance from Session, and if it doesn't find it, create a new instance and store it in Session.
更新
我可以看到如何检索会话变量,我的困惑在于如何设置会话变量.
I can see how the session var is retrieved, my confusion is around how the session var is set.
根据 Micah 的评论添加说明:第一次访问静态 Current 属性时,会创建一个新的 UserContext 实例,用新的 User 实例填充其 User 属性,并将 UserContext 实例存储在 Session 中.在同一会话中对 UserContext.Current
(以及因此 UserContext.Current.User
)的后续访问都在访问同一实例.
To add clarification following Micah's comment: the first time the static Current property is accessed, a new UserContext instance is created, its User property is populated with a new User instance, and the UserContext instance is stored in Session. Subsequent accesses to UserContext.Current
(and hence UserContext.Current.User
) in the same session are all accessing the same instance.
如果仍然不清楚,我建议使用调试器逐步完成.
If it's still not clear I suggest stepping through with a debugger.
public static UserContext Current
{
get
{
// If Session does not yet contain a UserContext instance ...
if (System.Web.HttpContext.Current.Session["UserContext"] == null)
{
// ... then create and initialize a new UserContext instance ...
UserContext uc = new UserContext();
uc.User = new User();
// ... and store it in Session where it will be available for
// subsequent requests during the same session.
System.Web.HttpContext.Current.Session["UserContext"] = uc;
}
// By the time we get here, Session contains a UserContext instance,
// so return it.
return (UserContext)System.Web.HttpContext.Current.Session["UserContext"];
}
}
这篇关于即使会话没有在属性设置器中更新,这个类似 Singleton 的 web 类如何保持会话数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!