TRULY Understanding ViewState这篇关于ViewState
的文章讲的很好,记录一下我读完后关于ViewState的理解。
ViewState背后通过StateBag
实现,StateBag类似HashTable功能,通过简直对记录控件属性。所不同的是,StateBag有记录属性是否被修改过的功能:被修改的属性被标记为Dirty
。
对控件属性的修改,在TrackViewState
调用前,不会被标记为Dirty
,而在TrackViewState
调用后,会被标记。而TrackViewState
的调用是在页面的OnInit
阶段,从子控件,一直到顶层的Page层层调用的。而这意味着,我们即使在Page的OnInit中初始化了控件的值,该值也会被ViewState Track
。
ViewState在前台体现为一个Base编码的字符串,该字符串的内容,来源于被标记为Dirty
的控件属性值的序列化结果。
在PostBack操作中,ViewState被回传,而页面控件被修改的值,是在OnInit后、OnLoad前被加载的,这意味着:
- 在OnInit中我们设置的值,不会覆盖页面的值
- 在OnLoad中我们设置的值,会覆盖页面回传的值,因此如果想在OnLoad中初始化控件,而不希望覆盖用户设置的值,需要加上
IsPostBack
的判断。
另外,如果不希望控件的值被存入ViewState,可以设置EnableViewState
为false,这不会影响PostBack操作中用户设置的值回传。
文章提到了几个常见的错误和更好的实践方式。
- 对于一些易于获取的轻量操作,比如初始化省市这样的下拉框,可以
- 禁用ViewState节省网络开销
- 将控件初始化放在OnInit中,这样不会覆盖PostBack值
- 这会导致服务端初始化操作压力增加,但是会提高网络传输效率
- 当开发控件时,默认值不应该在OnLoad中,那样会覆盖预设值;正确的做法是,直接通过StateBag中是否存在Key来判断是否需要使用默认值
- 当空间被加入页面时,所有的页面事件也会依次在控件中触发(init, load, render等等),因此控件属性的初始值如果不想被记录在ViewState中,可以在控件加入也面前,设置属性值