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

时间:2013-07-05 08:08:29

标签: c# asp.net .net session session-variables

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

HttpContext.Current.Session[listModelType + "ListModel"] = listModel;
listModel.ProductRows = new Collection<ProductRow>(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。

6 个答案:

答案 0 :(得分:11)

value types and reference types

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

如果您希望会话中的某个实例不受影响,则必须创建listModel的新实例。

答案 1 :(得分:4)

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

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

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

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

您将值0存储在会话中。 (不是i)的内存位置

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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

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

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

注意:JsonConvert来自c#

中的名称空间Newtonsoft.Json名称空间

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

if (HttpContext.Current.Session[listModelType + "ListModel"] != null)
{

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

}

答案 4 :(得分:0)

正确的方法应该是:

  int i = 0;
  i++;
  HttpContext.Current.Session["i"] = i;
HttpContext.Current.Session [“i”] 仍为1。

答案 5 :(得分:0)

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

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

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

注意:JsonConvert来自c#

中的名称空间Newtonsoft.Json名称空间

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

   if (HttpContext.Current.Session[listModelType + "ListModel"] != null) {

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

    }