即使会话没有在属性设置器中更新,这个类似 Singleton 的 web 类如何保持会话数据? [英] How does this Singleton-like web class persists session data, even though session is not updated in the property setters?

查看:43
本文介绍了即使会话没有在属性设置器中更新,这个类似 Singleton 的 web 类如何保持会话数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我有这个类似单例的 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;
    }

推荐答案

UserContextinstance 保存在 Session 中,下面一行:

The UserContextinstance 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆