2010-06-08 52 views
0

好吧,我有这个单身类的网络类,它使用会话来维护状态。我最初认为我将不得不在每个“集合”上操作会话变量,以便在会话中更新新值。不过,我尝试使用它,不知何故,它记住了状态。即使会话未在属性设置器中更新,此类Singleton类web类如何保持会话数据?

例如,如果一个页面上运行此代码:

UserContext.Current.User.FirstName = "Micah"; 

,并运行在不同的浏览器选项卡上的代码,名字是正确显示:

Response.Write(UserContext.Current.User.FirstName); 

谁能告诉我(证明)该数据如何在会话中持续存在?这里是类:

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; } 
} 

我加入这一块手表,并可以看到会话变量肯定是被设置的地方:

(UserContext)System.Web.HttpContext.Current.Session["UserContext"]; 

只要二传手被称为会话变量被即时更新:

set 
    { 
     HospitalField = value; //<--- here 
     ContractField = null; 
     ModelType = null; 
    } 

回答

2

UserContext实例保存在会话这一行:

System.Web.HttpContext.Current.Session["UserContext"] = uc; 

这不是一个单身人士。静态属性UserContext将尝试从Session中检索实例,如果它找不到它,请创建一个新实例并将其存储在Session中。

UPDATE

我可以看到会话VAR如何检索,我的困惑是围绕会议VAR是如何设置的。

要添加澄清以下Micah的评论:第一次访问静态Current属性,创建一个新的UserContext实例,其User属性填充一个新的User实例,并且UserContext实例存储在会话中。后续对同一会话中的UserContext.Current(因此UserContext.Current.User)的访问都访问相同的实例。

如果还不清楚,我建议逐步使用调试器。

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"]; 
    } 
} 
+0

我可以看到如何检索会话变量,我的困惑是如何设置会话变量。当我运行UserContext.Current.User.FirstName =“Micah”;我没有看到它被放回到会话var中的任何地方。会话设置的唯一时间是创建没有数据的新实例。 – 2010-06-08 14:20:21

+0

我不确定你是否明白我在问什么。只要代码调用“HospitalField = value”;会议从无效到填充医院名称。在该行执行之前,会话变量中的所有字段均为空。会议在哪里设置? 代码设置会话var的唯一地方是当它填充了一个带有空字段的新对象时。 – 2010-06-09 03:24:01

+0

当您调用“UserContext.Current.Hospital = value;”时,首先调用获取器UserContext.Current(并在Session中创建对象),然后调用“Hospital”设置器,此时该对象已创建在会议中。你是否尝试过使用调试器?您可能需要更改您的VS Debug设置,以便它进入属性以查看发生了什么。 – Joe 2010-06-09 04:25:33

0

而且在不同的浏览器 标签运行这段代码,名字显示正确 :

要保存它的会话。打开一个新标签可以使用与其他标签相同的会话信息(我不确定所有浏览器)。尝试打开一个新的浏览器窗口(不只是一个标签),看看会发生什么。

+0

我使用新的浏览器窗口获得相同的行为。 – 2010-06-08 14:21:55

+0

我的问题是*如何在会话中保存。 – 2010-06-09 13:48:55

1

乔是对的。您的用途是:UserContext.Current.User.FirstName

在获取器UserContext.Current中,您将获取对位于asp.net中会话对象内部的一段内存的引用。使用任何setter都应该/会改变这个内存,如果你在调试器或后面的代码行检查session对象,你应该看到你用setter设置的相同数据。

+0

这很有道理。它作为铸造对象返回,因此可以设置强类型属性。 – 2010-06-09 19:15:04