日期:2014-02-21  浏览次数:20400 次

与以前的ASP版本相比,ASP.NET有了很大的改进。这些改进之中,主要的一点就是新引入的服务端控件。现在我们就来一起研究ASP.NET中的HTMLControl和WebControl这两类服务端控件。

回忆:一个不使用服务端控件的例子

为了说明服务端控件所能带来的好处,我们现在用传统的ASP来做一个页面。这个页面的功能是根据用户选择的电吉它和功放组合,显示一些对这个组合的评论信息。这个页面完成后将如图1所示:


图1


从组合框里选择好吉它和功放的类型,然后按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类。

类名
功能
HtmlAnchorHTML <a>HtmlButtonHTML <button>HtmlContainerControl表示一个HTML服务端控件,该控件必须有一个结束标记HtmlControl表示一个HTML服务端控件HtmlFormHTML <form>HtmlGenericControl表示一个没有专门.NET Framework类的HTML服务端控件HtmlImageHTML <img>HtmlInputButtonHTML <input type= button>, <input type= submit>, 以及<input type= reset>HtmlInputCheckBoxHTML <input type= checkbox>HtmlInputControlHTML输入型控件的抽象类,这些输入控件包括 <input type=text>, <input type=submit>, 以及<input type= file>等HtmlInputFileHTML <input type= file>HtmlInputHiddenHTML <input type=hidden>HtmlInputImageHTML <input type= image>HtmlInputRadioButtonHTML <input type= radio> element on the serverHtmlInputTextHTML <input type= text> 和 <input type= password>HtmlSelectHTML <select>HtmlTableHTML <table>HtmlTableCell包含于HtmlTableRow中的单个的HTML <td>和<th> 元素HtmlTableCellCollection包含于HtmlTable 中的表格单元集合HtmlTableRow包含于HtmlTable 中的单个HTML <tr> 元素HtmlTableRowCollectionTableRow集合HtmlTextAreaHTML <textarea>


清单3展示了用ASP.NET HTMLControl写的“Axe 'n' Stacks”页面。注意到各个选择框、按钮、图像元素的布局都与传统的ASP代码的效果非常相似。当ASP.NET引擎遇到这些标记时,它们会将之映射为相应的HTMLControl。从代码可以看出,提交按钮(“Information”)被连接至消息处理例程FetchInfo_Click。注意FetchInfo_Click通过访问表单域来管理控件的方法。它首先检查传送进来的吉它、功放组合,再在文本框控件里填充入相应的内容。然后它设置好图像控件,在其中显示出正确的吉它、功放的图片。如图2。