asp.NET自定义服务器控件内部细节系列教程七(状态管理)
七 状态管理
从控件的生命周期中可知,在保存视图状态阶段,页面对控件树中的每个控件递归地调用SaveViewState方法。然后每个控件返回一个对象,该对象包含了控件在回传请求中用来恢复状态所需要的信息。在生成阶段,页面利用System.Web.UI.LosFormatter类的实例将视图状态串行化成字符串表示,然后在__VIEWSTATE隐藏域中往返传送到客户端。
Contorl类的默认实现将状态管理委托给了ViewState属性,ViewState属性是一个复杂属性,该属性是一个StateBag类型,是一个字典,StateBag类实现了IStateManager接口来实现状态管理。StateBag保存了键/值对,其中键是字符串而值是对象。当某个对象添加到StateBag实例中时,StageBag自动为该对象存储一个附加位,它用来标志存储的对象是否修改过。
Control类用于IStateManager接口中相同的成员来实现状态管理,尽管Control并不实现IStateManager接口,只是委托给了实现了IStateManager接口类型的StateBag类,也就是委托给了ViewState属性。在自己的复杂类型状态管理中,可以模仿Control的这种行为,以实现自定义复杂属性的状态管理。
1。IStateManager接口
public interface IStateManager
{
bool IsTrackingViewState{get;}
void LoadViewState(object state);
object SaveViewState();
void TrackViewState();
}
先分析Control类是如何通过委托ViewState属性来实现默认的状态管理的:
private StateBag _viewState ;
protected virtual StateBag ViewState
{
get
{
if(_viewState != null){return _viewState;}
_viewState = new StateBag(ViewStateIgnoresCase);
if(IsTrackingViewState)
_viewState. IsTrackingViewState();
return _viewState;
}
}
protected virtual void TrackViewState()
{
if(_viewState != null)
{
_viewState.TrackViewState();
}
}
protected virtual object SaveViewState()
{
if(_viewState != null)
{
return _viewState.SaveViewState();
}
return null ;
}
protected virtual void LoadViewState(object savedState)
{
if(_viewState != null)
{
viewState.LoadViewState(savedState);
}
}
当在ViewState中保存属性时,它们的状态是自动维护的。任何保存在ViewState中的类型必须是通过LosFormatter串行化的。
当控件定义了复杂属性时,通常使用ViewState字典来管理这些属性的状态是不可能的,用来表示复杂属性的自定义类型可以通过实现IStateManager接口参与状态管理。