与以前的ASP版本相比,ASP.NET有了很大的改进。这些改进之中,主要的一点就是新引入的服务端控件。现在我们就来一起研究ASP.NET中的HTMLControl和WebControl这两类服务端控件。
回忆:一个不使用服务端控件的例子
为了说明服务端控件所能带来的好处,我们现在用传统的ASP来做一个页面。这个页面的功能是根据用户选择的电吉它和功放组合,显示一些对这个组合的评论信息。
从组合框里选择好吉它和功放的类型,然后按Information按钮。ASP代码根据选择的吉它和功放的型号做一起判断,并给出有关此组合的一些评论。清单1显示了这个页面的传统ASP代码。
当我们在写ASP代码的时候,我们事实上在告诉ASP DLL去生成一些特定的HTML标记和文本信息。在我们的ASP代码里已经明确包含了这些标记和文本。ASP DLL将<html>、<body>以及<form>这些标记扔给客户端,然后接着是标题行“Axe 'n' Stacks”,然后接着发给客户端<select>标记去告诉它显示一个组合框。
在这个例子中,为了正确在组合框里显示我们所选择的选项,我们不得不写一大段的if…then语句才能实现。这段代码虽然看上去有些冗长,但毕竟它能够实现一个只用HTML几乎无法实现的功能。
清单2是我们的ASP程序运行时发给客户端的HTML代码,其中的<select>标记显示出一个组合框,这个组合框显示出我们所有可以选择的项目,同时高亮条停留在我们实际选择的一项上。
这里存在的一个基本问题是,传送HTML的HTTP协议是一个“无连接”协议,因此,它也是一个“无状态”协议。服务端并不会保存客户端每次请求之间的状态。而我们桌面应用中使用组合框以及其他控件的时候,保持这种状态很容易,因为所有的代码都在同一个屋檐下——只会有一个用户在点击你的程序上的按钮。
Web开发时可就不同了。由于Web是基于HTTP这个“无连接”的协议,有可能每次对你页面的访问都来自于一个不同的客户。因此,作为Web开发者的我们必须自己写代码去追踪每个用户在不同次访问之间的状态。在上面的例子中,我们通过获得并解析查询字符串来得到用户上一次的状态,然后才能选取适当的<option>项,给它加入“selected”属性。
如果我们编程的语言给我们提供了这些基础的服务,岂不妙哉?
非常幸运,ASP.NET正是为此目的引入了服务端控件。
ASP.NET中的服务端控件
传统的ASP代码是一堆HTML与可执行脚本代码的混合物。每当有一个客户提交请求,服务器便生成一堆的HTML回应码。不幸的是,随着程序逻辑的复杂,这种ASP代码最后变得和20世纪80年代初那些便宜的编程教科书上非结构化的Basic程序一样,杂乱不堪。
如前所示,经典的ASP
Web处理包括手动解析表单数据和处理控件。ASP.NET引入服务端控件使得对控件的访问变得更加直观。由于HTTP是一个“无连接”协议,客户状态的保持一直是个令人头痛的问题。服务端控件能够自动保持用户在不同的回传(Postback)中的状态,使我们不用再费神一次又一次去写类似的代码。
使用服务端控件进行开发时,与我们习惯的桌面开发更为相似了。在桌面开发时,你可以认为同一个控件的状态在整个桌面程序的运行期内都是一致的;服务端控件使你在进行Web开发的时候可以假设同样的事情,虽然Web应用的UI正在被成千上万的人访问。
前面我们曾经提到,ASP.NET的服务端控件包括两种开式:HTMLControl和WebControl。这样控件将内部的一系列烦琐的管理操作封装起来,我们只需与最关心的部分打交道。不同于传统的ASP,我们不用在代码中手工嵌入各种HTML的标记,我们只需使用HTMLControl和WebControl这些控件即可,它们会帮我们处理这一切。它们会自已维护不同Session之间的状态,使我们能够比传统的ASP程序员更早地完成工作回家!
现在让我们从HTMLControl开始。
HTMLControls
ASP.NET中的HTMLControl和WebControl都是标准的基于CLR的控件。如同其他的所有CLR类一样,它们也从System.Object对象继承而来,而且它们也一样有属性、方法,以及代理和事件。它们的主要功能就是在Web页面上管理控件。
HTMLControl的类与HTML中的各种标记一一对应。例如,当ASP.NET引擎发现你在ASP代码中定义了一个Button,它便会将之包装为一个HtmlButton的类。当你需要在程序中访问这个Button时,你只需访问这个HtmlButton类的对象即可。
下表列出了目前ASP.NET中支持的HtmlButton类。
类名
功能
HtmlAnchor
HTML <a>
HtmlButton
HTML <button>
HtmlContainerControl
表示一个HTML服务端控件,该控件必须有一个结束标记
HtmlControl
表示一个HTML服务端控件
HtmlForm
HTML <form>
HtmlGenericControl
表示一个没有专门.NET
Framework类的HTML服务端控件
HtmlImage
HTML <img>
HtmlInputButton
HTML <input type= button>,
<input type= submit>, 以及<input type= reset>
HtmlInputCheckBox
HTML <input type= checkbox>
HtmlInputControl
HTML输入型控件的抽象类,这些输入控件包括 <input type=text>, <input type=submit>, 以及<input type= file>等
HtmlInputFile
HTML <input type= file>
HtmlInputHidden
HTML <input type=hidden>
HtmlInputImage
HTML <input type= image>
HtmlInputRadioButton
HTML <input type= radio> element on the server
HtmlInputText
HTML <input type= text> 和 <input type= password>
HtmlSelect
HTML <select>
HtmlTable
HTML <table>
HtmlTableCell
包含于HtmlTableRow中的单个的HTML <td>和<th> 元素
HtmlTableCellCollection
包含于HtmlTable 中的表格单元集合
HtmlTableRow
包含于HtmlTable 中的单个HTML <tr>
元素
HtmlTableRowCollection
TableRow集合
HtmlTextArea
HTML <textarea>
清单3展示了用ASP.NET HTMLControl写的“Axe 'n' Stacks”页面。注意到各个选择框、按钮、图像元素的布局都与传统的ASP代码的效果非常相似。当ASP.NET引擎遇到这些标记时,它们会将之映射为相应的HTMLControl。从代码可以看出,提交按钮(“Information”)被连接至消息处理例程FetchInfo_Click。注意FetchInfo_Click通过访问表单域来管理控件的方法。它首先检查传送进来的吉它、功放组合,再在文本框控件里填充入相应的内容。然后它设置好图像控件,在其中显示出正确的吉它、功放的图片。
基本上,如果你在代码中用传统的ASP方式定义一个控件,并给它加上“runat=server”属性,ASP.NET就会将之包装成一个HTMLControl。
WebControls
大致来说,WebControl和HTMLControl的功能差不多。很多的WebControl也可以直接映射到标准的HTML控件。但是,WebControl提供了一个比HTMLControl更加一致的接口。例如,有时候HTMLControl的背景颜色可以通过Style属性来修改,有时候却也可通过其他专门属性进行修改。而对WebControl却总是通过BackColor属性来进行修改。
WebControl与HTMLControl的定义方法有些不一样。清单4是“Axe 'n'
Stacks”网页的WebControl版本。注意到选择用的组合框在WebControl中被定义成“asp:DropDownList”,其内容也用asp:ListItem定义。类似地,WebControl用asp:Button来定义Button,图像和文本框控件也被分别定义成asp:Image和asp:TextBox。如果你读读程序顶部的消息处理代码,还会发现很多控件用于存储数据的属性的名字也已经发生了改变。例如,HTMLSelect的Value属性改成了DropDownList's SelectedItem.Text属性。除此之外,程序的结构与用HTMLControl书写的基本相同。
复杂些的WebControls
前面已经提到,WebControl有着比HTMLControl更为一致的接口。此外WebControl比HTMLControl的一个优势在于WebControl提供了一些更为复杂但很有用的控件,包括AdRotator,Calendar, 以及DataGrid等。AdRotator控件接收一些图像(如JPG和GIF文件),并且将它们分别映射到一系列的URL。每次页面刷新时,AdRotator就会随机抽取一个图像来显示。当它被点击时,页面会被重定向到相应的URL。Calendar控件可以在浏览器里显示一个功能较强的日历表;而DataGrid控件则相当于一个mini型的电子表格。
结论
今天,基于Web的开发都可归结为HTTP的请求与回复,而在很多时候,这些回复需要将控件的标记回送给浏览器。当直接使用ASP来编程的时候,你经常会需要花很多的时间和精力来保证控件在不同的请求中保持一致性。毕竟,这个世界已经不再是桌面应用的天下!ASP.NET的控件能帮你解决掉很多烦杂的琐事,让你感觉就象在用MFC或Visual Basic做开发,让你的应用分布于全球的计算机上,时刻被成千上万的用户所访问。