在C#中更新对象时会话对象发生更改

我有这个非常奇怪的问题,我确信我在这里遗漏了一些明显的东西。 我有这两行:

HttpContext.Current.Session[listModelType + "ListModel"] = listModel; listModel.ProductRows = new Collection(listModel.ProductRows.Where(r => r.ParentRowId == 0).ToList()); 

执行第二行后,我的会话对象也会更新(根据Visual Studio中的“Watch”)

我在这里想念的是什么?

我试过了

 int i = 0; HttpContext.Current.Session["i"] = i; i++; 

和HttpContext.Current.Session [“i”]保持为0。

请参阅值类型和引用类型 。

int是一个值类型,因此将在赋值时“按原样”存储; listModel是一个引用类型,因此您在会话中存储对象的引用,而不是对象的值。

如果您希望会话中的listModel实例listModel则必须创建listModel的新实例。

在第一个示例中,您将存储对象的引用(列出内存位置)。 因此,如果list更新,它将反映在会话中。 这是一种参考类型。

在第二个示例中,您使用的是值类型:

 int i = 0; HttpContext.Current.Session["i"] = i; i++; 

你声明i并将其设置为0(值类型)

您将值0存储在会话中。 (不是我的记忆位置)

您递增i但会话仍然具有值0

在第一个示例中,您的会话变量指向reference因此它会更新,因为两个引用指向相同的值。

第二个会话变量指向primitive (value)类型,因此它们具有单独的值副本。

在第一个示例中,您的会话变量指向引用,因此它会更新,因为两个引用指向相同的值。

所以在分配给会话之前,你将它转换为Json,然后分配

 HttpContext.Current.Session[listModelType + "ListModel"] = JsonConvert.SerializeObject(listModel); 

注意:JsonConvert来自c#中的名称空间Newtonsoft.Json命名空间

在第二行中,如果listModel对象中的值更改不反映会话。 但是当你想要从会话中检索值时,你应该转换为Json的对象forms

 if (HttpContext.Current.Session[listModelType + "ListModel"] != null) { listModel = JsonConvert.DeserializeObject<*CLASS name of lsitmodel*>((string)HttpContext.Current.Session[listModelType + "ListModel"]); } 

正确的方法应该是:

  int i = 0; i++; HttpContext.Current.Session["i"] = i; 

HttpContext.Current.Session [“i”]仍为1。

在第一个示例中,您的会话变量指向引用,因此它会更新,因为两个引用指向相同的值。

所以在分配给会话之前,你将它转换为Json,然后分配

  HttpContext.Current.Session[listModelType + "ListModel"] = JsonConvert.SerializeObject(listModel); 

注意:JsonConvert来自c#中的名称空间Newtonsoft.Json命名空间

在第二行中,如果listModel对象中的值更改不反映会话。 但是当你想要从会话中检索值时,你应该转换为Json的对象forms

  if (HttpContext.Current.Session[listModelType + "ListModel"] != null) { listModel = JsonConvert.DeserializeObject<*CLASS name of lsitmodel*>((string)HttpContext.Current.Session[listModelType + "ListModel"]); }