更新链接变量时会话更新

时间:2012-06-25 07:42:26

标签: asp.net session-state

我在这里看到很多关于在Sessions中存储列表然后检索它们的帖子。大多数答案都遵循这种技术:

if(Session["Strings"]==null)
{
      //Create List
      List<string> strings = new List<string>();
      ...
      Session["Strings"] = strings;
}
else
      strings =   Session["Strings"] as List<string>

//Add item to list
strings.Add("asdf");

我试过这个,但是一旦我更新列表,会话变量也会更新,并且在回发时我会在Session中获得更新的值。这是预期的行为吗?如何使用它以便会话不更新?我甚至试图在使用后将'strings'变量设置为null,但会话在每次回发时仍然有添加的项目。

也许我可以添加一些具体的代码来解释。

假设我的页面上有一个按钮点击事件:

     protected void GoClicked(object sender, EventArgs e)
 {

    List<string> a;
    if(Session["data"] == null)
    {
        a = new List<string>();
        a.Add("abc");
        a.Add("def");
        a.Add("ghi");

        Session["data"] = a;
    }
    else
    {
        a = (Session["data"] as List<string>);
    }
    a.Add("jkl");
    foreach (string s in a)
    {
        lblTest.Text += s + "<br />";
    }
}

每次单击按钮时,我都希望'a'只包含4个值,因为我从Session中获取它并且它是一个局部变量。但实际上每次单击它时,都会添加值'jkl',因此值的数量会不断增加。我不希望这种情况发生。我希望我更清楚。

2 个答案:

答案 0 :(得分:0)

我认为ViewState是您搜索的那个。尝试将它们保留在ViewState上以将此变量保留在页面内。这是您可以使用的代码:

const string _cListWStringsName = "cListWStrings_cnst";

public List<string> cListWStrings
{
    set
    {
        ViewState[_cListWStringsName] = value;
    }
    get
    {
        if (ViewState[_cListWStringsName] is List<string>)
        {
            return (List<string>)ViewState[_cListWStringsName];
        }
        else
        {
            var NewOne = new List<string>();

            ViewState[_cListWStringsName] = NewOne;

            return NewOne;
        }
    }
}

答案 1 :(得分:0)

第一次单击按钮时,会添加四个值“abc”,“def”,“ghi”和“jkl”。并且在每次连续点击时添加“jkl”,因为a.Add(“jkl”)位于if子句之外。你需要在if子句中移动它,这里是:

 protected void GoClicked(object sender, EventArgs e)
 {

    List<string> a;
    if(Session["data"] == null)
    {
        a = new List<string>();
        a.Add("abc");
        a.Add("def");
        a.Add("ghi");
        a.Add("jkl");//Move here
        Session["data"] = a;
    }
    else
    {
        a = (Session["data"] as List<string>);
    }

    foreach (string s in a)
    {
        lblTest.Text += s + "<br />";
    }
} 

* UPDATE: * Session包含对List的引用,因此也是如此。两者都引用相同的列表,因此如果您在会话或会话中进行更改,则引用的列表将会更改。请记住,Session正在存储引用而不是值。现在,为什么“ijk”不断添加?因为列表永远不会超出范围(即使在你的方法完成执行之后),它只会在Session中保留,所以当你的代码将“ijk”添加到“a”时,它实际上将值添加到列表中。因此,它不断将值“ijk”添加到Session引用的列表中。