视图状态机制下的IStateManager接口
本文节选自《庖丁解牛:纵向切入ASP.NET 3.5控件和组件开发技术》一书
.NET框架为自定义视图状态管理提供了System.Web.UI.IStateManager接口,定义了任何类为支持服务器控件的视图状态管理而必须实现的属性和方法,服务器控件的视图状态由控件属性的累计值组成。该接口包括保存并加载服务器控件的视图状态值的方法,以及一个指示控件跟踪其视图状态的更改的方法。此接口的成员与Control类中的对应方法具有相同的语义。
若要自定义ASP.NET应用程序管理服务器控件视图状态的方式,必须创建一个实现此接口的类。代码如下:
/// <summary>
/// 获得本书更多内容,请看:
/// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx
/// </summary>
public interface IStateManager
{
// Methods
object SaveViewState();
void LoadViewState(object state);
void TrackViewState();
// Properties
bool IsTrackingViewState { get; }
}
该接口包括以下几个成员:
SaveViewState:保存自从页回发到服务器后发生的所有服务器控件视图状态更改,最后返回最新更改后的视图状态对象。如果没有与控件关联的视图状态,则此方法返回空。保存了视图状态后,页面类会把所有控件的视图状态对象转换为可以通过网络传输的Base64格式字符串形式,最终该字符串对象作为存储在Hidden元素中的变量返回给客户端。使用自定义视图状态时,一般使用SaveViewState和LoadViewState组合完成状态管理。
LoadViewState:把SaveViewState方法保存的上一个页面的视图信息还原到控件复杂属性中。
TrackViewState:在服务器控件的生存期内,将在Init事件结束时自动调用该方法。在开发模板数据绑定控件时调用此方法。此方法提醒ASP.NET监视服务器控件视图状态的更改。如果控件没调用TrackViewState()方法,则本次对控件属性的修改将不会被添加到__VIEWSTATE隐藏域中,下次页面回发时,控件的属性只恢复为之前的旧值。从性能角度讲,为了减少在网络上的传输量,应该只保存“变化”的数据到视图状态中,即仅对需要保存到视图中的数据才调用此方法。其实TrackViewState只是控制一个布尔值作标记,往视图中增加数据时,会判断该值是否为true,如果为true才将其加入视图数据。下节讲解StateBag类时还会说明其内部原理。
IsTrackingViewState:返回当前控件视图是否被ASP.NET框架监视(是否存储该属性到视图中,与TrackViewState方法控制的是同一个标记)。
或许读者会想到,之前在开发控件时使用过视图存储属性值,如ViewState["Text"],而没有使用IStateManager接口控件为什么这样也能够正确保存值呢?在后面的6.2.3小节会说明其原因,事实上它也是使用了IStateManger接口,只是Control提供了更方便的管理而已。