"引用对象"的逻辑如何?使用ViewState?

时间:2015-09-07 22:01:51

标签: asp.net viewstate

我将列表存储到ViewState。每当我对列表进行更改时,ViewState都会自动更新。当我在StackOverflow中检查了几个相关帖子时,我了解到这一点,因为ViewState存储了对List对象的引用。

但是,我想了解更多细节。我虽然存储在ViewState中的信息通过PostBacks传播。然后,整个列表应该被序列化并存储在隐藏字段中,是吗?如果它存储对List对象的引用,那么Server内存中对象的生命周期是多少?每次服务器收到请求时是否重新创建?

任何人都能解释一下这种机制吗?

1 个答案:

答案 0 :(得分:1)

让我举个简单的例子:

public partial class WebForm1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        List<string> myList = new List<string> { "a", "b", "c" };

        Response.Write(string.Join(";", myList.ToArray()) + "<br>");

        ViewState["myList"] = myList;

        myList.Add("d");

        List<string> myListSavedInViewstate = (List<string>)ViewState["myList"];

        Response.Write(string.Join(";", myListSavedInViewstate.ToArray()) + "<br>");

        myListSavedInViewstate.Add("e");

        Response.Write(string.Join(";", myList.ToArray()) + "<br>");

        Response.Write(myList.GetHashCode() + "<br>");
        Response.Write(myListSavedInViewstate.GetHashCode() + "<br>");
    }
}

输出结果为:

a;b;c
a;b;c;d
a;b;c;d;e
34781257
34781257

所以基本上是的,Viewstate在整个页面生命周期中保留一个引用而不是对象(引用类型)的副本。但是,只要请求结束,Viewstate就会在隐藏字段中序列化并返回到客户端,并且Viewstate实例将被删除。发生回发时,将反序列化并重新创建viewstate。但是,重新创建的viewstate实例只是它用于在页面生命周期执行期间保存引用的所有对象的浅表副本。这就是为什么在viewstate中允许的所有类都必须实现ISerializable接口(或者必须具有Seri​​alizable属性)。

然而,这只是冰山一角;)如果你想阅读更多关于这个主题的话,这里有关于viewstate的非常好的写作。

http://weblogs.asp.net/infinitiesloop/Truly-Understanding-Viewstate