2006年10月18日星期三

控件 ViewState 属性的值保存去哪里了

看过MSDN的都知道,存取ViewState有两种方法:

  • 直接操作控件的ViewState属性,通过this.ViewState[key]就可以直接进行读写。
  • 重写控件的LoadViewState和SaveViewState方法。在LoadViewState中系统会将此控件以ViewState保存的信息作为一个object类型参数传入,控件需要自己将信息unboxing出来。在SaveViewState中,控件需要自己将想通过ViewState保存的信息boxing到一个object里面,然后return给系统。

那么到底这两种方法读写ViewState有什么不同呢?

使用Reflector看看Control的LoadViewState与SaveViewState方法你就会发现,其实控件的ViewState属性也就是一个特殊的控件属性,类型为StateBag,由于Control已经为你写好了将StateBag存取到真正的ViewState的方法,所以只要你继承Control控件你就可以放心地把值存到StateBag里面去,而这些值最终会保存到真正的ViewState中。

就这么简单?还差一点,就是StateBag这个字典的每一个项目类型为StateItem,而StateItem有一个IsDirty的属性。只有这个属性为true的StateItem才会被保存到ViewState中。我们在OnInit之后使用this.ViewState[key]读写时该属性都为true,所以StateItem都会被保存。但如果你想要某个StateItem临时不保存到ViewState,那就可以执行this.ViewState.SetItemDirty(key, false)。例如我们熟悉的TextBox,在它的TextBoxMode为Password时它就会通过上述方式让this.ViewState["Text"]值不保存到真正的ViewState中,也就确保了你无法通过ViewState窃取密码,同时也导致了该TextBox的OnTextChanged事件无法正常触发。

那还有什么要说的吗?要说明的就是StateBag的存取所受到的限制。StateBag的存取,与你手动重写LoadViewState/SaveViewState保存的其它值一样,在LoadViewState之前StateBag并没有任何值,在SaveViewState后的任何更新不保存到ViewState中。

没有评论:

发表评论