.Net更新Session对象的副作用

时间:2012-08-22 19:18:01

标签: c# session webforms

我在.Net Webforms项目中对Session个对象有一些奇怪的(至少对我来说)功能。我在Sessions中传递对象并且我没有使用任何global变量。我有一个描述如下的方法:

 private int Foo()
 {
     RmRule ruleInEdit = (RmRule)Session["ruleInEdit"];
     //here ruleInEdit.subjectAreaID=0
     bool isValid = Validate();
     if (isValid)
     {
        //do some stuff
        //here ruleInEdit.subjectAreaID is 10 instead of 0
        //the Validate function modified the ruleInEdit object 
      }

    //other code
  }

   private bool Validate()
   {
       bool isValid;
       //check some stuff
       RmRule rule = (RmRule)Session["ruleInEdit"];
       rule.subjectAreaID = 10;
       Session["ruleInEdit"] = rule;
       return isValid;
    }

我认为subjectAreaID的值仍应为0但显然我误解了一些东西。当我将对象写回ruleInEdit时,.Net如何(或为什么)自动更新Session对象。

  • 在原始方法Foo中,我不应该强制ruleInEdit再次读取会话以获取更新的对象和属性吗?
  • 由于我初始化它的方式,此对象是否与会话范围相关联?

2 个答案:

答案 0 :(得分:5)

您不必将对象写回会话集合,它永远不会离开。

只有一个对象实例,当您从会话集合中读取它时,它不会被复制。您对该对象所做的任何更改都会立即显示在查看同一实例(即同一会话)的所有代码中。

会话集合中存储的内容只是对象的引用。对象本身存储在堆上。

答案 1 :(得分:3)

当您使用InProc(默认情况下)会话存储时,则不会发生序列化。您是自定义类的操作,它是引用类型。因此,当您的方法Validate从会话中检索对象时,实际上它只是您正在更改原始对象的指针。 换句话说,RmRule类型的对象在Foo和Validate方法中是相同的。

您期望的行为是在将应用程序设置切换到SQL Server中的存储会话之后。