Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 即使在属性设置器中没有更新会话,这个类似于单例的web类如何持久化会话数据?_C#_Singleton_Session State_Session Variables - Fatal编程技术网

C# 即使在属性设置器中没有更新会话,这个类似于单例的web类如何持久化会话数据?

C# 即使在属性设置器中没有更新会话,这个类似于单例的web类如何持久化会话数据?,c#,singleton,session-state,session-variables,C#,Singleton,Session State,Session Variables,好的,我有一个类似单例的web类,它使用会话来维护状态。我最初认为我必须操作每个“集合”上的会话变量,以便在会话中更新新值。然而,我试着按原样使用它,不知怎的,它记住了状态 例如,如果在一个页面上运行此代码: UserContext.Current.User.FirstName = "Micah"; 并在其他浏览器选项卡中运行此代码,则正确显示FirstName: Response.Write(UserContext.Current.User.FirstName); 有人能告诉我(证明)这些

好的,我有一个类似单例的web类,它使用会话来维护状态。我最初认为我必须操作每个“集合”上的会话变量,以便在会话中更新新值。然而,我试着按原样使用它,不知怎的,它记住了状态

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

UserContext.Current.User.FirstName = "Micah";
并在其他浏览器选项卡中运行此代码,则正确显示FirstName:

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"];
一旦调用setter,就会立即更新会话变量:

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

HospitalField=value;//在会话中使用此行保存
UserContext
实例:

System.Web.HttpContext.Current.Session["UserContext"] = uc;
它不是单一实例。静态属性
UserContext
将尝试从会话检索实例,如果找不到实例,则创建一个新实例并将其存储在会话中

更新


我可以看到会话变量是如何检索的,我的困惑在于会话变量是如何设置的

在Micah的评论之后添加澄清:第一次访问静态当前属性时,将创建一个新的UserContext实例,其用户属性将填充一个新的用户实例,并且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"]; 
    } 
} 

UserContext
实例保存在会话中,并带有以下行:

System.Web.HttpContext.Current.Session["UserContext"] = uc;
它不是单一实例。静态属性
UserContext
将尝试从会话检索实例,如果找不到实例,则创建一个新实例并将其存储在会话中

更新


我可以看到会话变量是如何检索的,我的困惑在于会话变量是如何设置的

在Micah的评论之后添加澄清:第一次访问静态当前属性时,将创建一个新的UserContext实例,其用户属性将填充一个新的用户实例,并且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"]; 
    } 
} 
并以不同的方式运行此代码 “浏览器”选项卡上,将显示FirstName 正确地说:

Response.Write(UserContext.Current.User.FirstName);
您正在会话中保存它。打开一个新选项卡可以使用与另一个选项卡相同的会话信息(我不确定是否所有浏览器)。请尝试打开一个新的浏览器窗口(不仅仅是选项卡),然后看看会发生什么

并以不同的方式运行此代码 “浏览器”选项卡上,将显示FirstName 正确地说:

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

您正在会话中保存它。打开一个新选项卡可以使用与其他选项卡相同的会话信息(我不确定所有浏览器)。尝试打开一个新的浏览器窗口(不仅仅是一个选项卡),看看会发生什么。

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


UserContext.Current
的getter中,您将返回一个对asp.net中会话对象内部内存段的引用。使用任何setter都应该/将会更改该内存,如果您在调试器中或在后续代码行中检查会话对象,您应该会看到与您相同的数据用你的setter设置。

乔是对的。你的用法是:
UserContext.Current.User.FirstName


UserContext.Current
的getter中,您将返回一个对asp.net中会话对象内部内存段的引用。使用任何setter都应该/将会更改该内存,如果您在调试器中或在后续代码行中检查会话对象,您应该会看到与您相同的数据使用setter设置。

我可以看到会话变量是如何检索的,我的困惑在于会话变量是如何设置的。当我运行UserContext.Current.User.FirstName=“Micah”;我看不到它被放回会话变量的任何地方。唯一设置会话的时间是在创建没有数据的新实例时。我不确定您是否理解我的要求。只要代码调用“HospitalField=value;”会话从null变为使用医院名称填充。在该行执行之前,会话变量中的所有字段都为null。会话设置在哪里?代码设置会话变量的唯一位置是在使用带有空字段的新对象填充会话变量时。当调用“UserContext.Current.hospital=value;”,首先调用getter UserContext.Current(并在会话中创建对象),然后调用“Hospital”调用setter时,对象已在会话中创建。您是否尝试过使用调试器进行调试?您可能需要更改VS Debug设置,使其进入属性以查看发生了什么。@Micah-从您的问题和困惑中,我感觉到您正在努力理解与甚至是一个“属性”和一个“变量”。属性可能有一个备份变量,但它不必有。在这种情况下,属性的备份存储是会话。属性没有自己的独立生存期。相反,它是一个代码块,伪装为数据成员,但隐藏后端实现。我可以看到如何检索会话变量,我的困惑在于会话变量是如何设置的。当我运行UserContext.Current.User.FirstName=“Micah”时,我看不到它的任何地方