ASP.NET组件设计Step by Step,4

如果我们的服务器控件需要较完备的GUI,譬如需要控制HTML元素的附加属性字体、颜色、高度等,那么应当从Control的子类WebControl继承,以得到所需的基础性能。从WebControl类派生,需要遵守通常如下的约定:

1、 包含从System.Web.UI.WebControl的命名空间的引用

2、 不能够重载Render方法直接向输出流提供数据,而应当重载RenderContents方法来实现

3、 通常情况下,WebControl的派生类最终在输出流中表现为<span>标签,但是如果自己希望使用其它的标签,就应当重载WebControl的tagKey属性或者TagName属性。

经验(或者说MS建议):

1、 如果控件生成非可视化元素或显示给非HTML客户端,那么应当选用Control作为符类继承。如<meta><xml>等标签

2、 提供HTML界面的从WebControl继承

3、 扩展修改功能时应当从一个已存控件派生,但是不要从System.Web.UI.HtmlControls命名空间派生,因为vs.net设计器不承认从该类派生的控件

为了能够支持设计器,实现设计期,那么需要考虑attribute(元数据)的编程。

视图状态

web编程很重要的一个方面是状态管理,也就是解决在无状态的http协议基础上的状态管理问题。在asp类web编程技术时代,这通常通过以下技术手段来解决:

1、 Session

2、 Cookies

3、 隐藏变量

4、 URL携参

然而,以上方案都有自身的缺陷,譬如Session不宜扩展,Cookies在特定情况下可能不可用,隐藏变量不易管理,URL携参有长度限制且容量有限。。。

综合考虑,MS提出了基于隐藏变量方案的ViewState(视图)的概念,通过视图保存2个asp.net页间的服务器端控件状态。视图是如何工作的呢?

在处理一个Web请求后,页面框架会收集页面控件树中所有控件的状态并且创建一个视图对象。每一个Control都有一个ViewState字典保存自己的状态,当输出html到客户时将全部ViewState进行串行化为一个字符串表达式,作为隐含变量发送到客户端,通常情况下我们将视图的串行化子符串在服务器同客户端间进行传递,上一个请求的隐含变量会回传到服务器端进行并行化,然后“还原”给服务器控件。本质上,是一个隐含变量,但是在隐含变量基础上加入了asp.net的管理功能,这就是视图的本质。

Control的EnableViewState决定了控件是否同意将自己的状态交给自动化的视图管理。

当一个控件需要保存状态时候,没人可以支持保存的属性为int32 boolean 等“简单原生”数据类型。如果是较为复杂的属性值类型,需要编程者提供类型转换器,将值数据转换为字符串,若未提供,那么采用代价高昂的二进制串行化功能(逐个byte的进行)。视图数据在传递过程中通过传递一个附加的摘要来确保数据不被篡改(但无法保证不被窥探,毕竟base64编码近乎明文)。