第6章 使用ASP.NET AJAX
ASP.NET AJAX是从ASP.NET 2.0开始美国微软公司推出的一种新技术。它是一种基于Ajax技术的ASP.NET编程模式,使用ASP.NET AJAX创建的Web应用程序能解决ASP.NET编程模式带来的页面刷新问题。
除此之外,使用ASP.NET AJAX编程模型,既可以继续使用服务器端代码实现程序的功能,又可以实现类似Windows应用程序的“胖客户端”效果,给用户以更好的感受和更强的人机交互能力,同时还可以提升浏览器的独立性。
6.1 Ajax和ASP.NET AJAX概述
Ajax是“Asynchronous JavaScript and XML”的英文缩写(异步JavaScript和XML),它是一种综合异步通信、JavaScript和XML等多种技术的、新的编程方式。如果从用户看到的实际效果来看,也可以形象地将其称为“无页面刷新”。
ASP.NET AJAX是美国微软公司将Ajax技术与ASP.NET编程模式相结合的产物,是一种具有Ajax风格的异步编程模型。
6.1.1 Ajax的概念
Ajax的核心是使客户端的JavaScript脚本程序能实现异步执行。所谓“异步执行”是相对于“同步执行”而言的,在同步执行方式中代码必须按顺序逐一执行,如果前面的代码需要10分钟的操作,那么后面的代码只能等待10分钟后才能执行。
例如,在ASP.NET环境中,当用户单击一个按钮时,浏览器会将单击事件传递给服务器,并等待服务器的响应,在此期间应用程序与用户间的交互暂时被停止,在收到服务器返回的请求结果后,客户端要根据返回结果刷新整个页面,与用户的交互才能继续进行。
在异步执行方式中,一旦前面的代码开始执行,后面的代码随之进入执行状态,而不必等待前面代码执行结束。
Ajax主要包括以下一些内容。
1)使用HTML+CSS来表示页面信息。
2)使用JavaScript操作文档对象模型(Document Object Model,DOM)。
3)使用XML和扩展样式表转换(EXtensible Stylesheet Language Transformations,XSLT)进行数据交换及相关操作。
4)使用XmlHttpRequest对象与Web服务器进行异步数据交换。
5)使用JavaScript将各部分内容绑定在一起。
Ajax实现的基本原理是,当用户与浏览器中的页面进行交互时,将触发页面元素对象的相应事件,客户端捕获这些事件后,如果需要将交互动作引起的逻辑实现提交给服务器进行处理,则将要处理的数据(包括状态描述)转换为XML格式的字符串,并使用异步传输方式提交给服务器。服务器处理结束后,同样使用XML格式和异步传输方式将处理结果送回。客户端从返回结果中提取需要的部分,交由JavaScript对网页进行“局部更新”,而不是刷新整个页面。
对于一些不需要提交给服务器的数据或行为,客户端可直接使用JavaScript代码处理。这就免去了重新从服务器端加载页面而导致的延迟,减少了客户端用户的等待时间。由于JavaScript是在客户端直接执行的,因此能方便地完成一些特殊功能,如动态控制元素的外观、及时响应某些键盘和鼠标动作等。
由于Ajax采用了“按需要取数据”的基本理念,减少了数据的实际读取量,从而减轻了对服务器和网络的压力。此外,Ajax使用XmlHttpRequest发送请求来得到服务器应答数据,在不重载整个页面的情况下通过JavaScript操作DOM,所以即使需要从服务器得到大量数据,也不会让用户面对一个“白屏”。只有当所有数据接收完毕,才由JavaScript更新部分页面,而且这个更新也是瞬间的,用户几乎感觉不到。
6.1.2 ASP.NET AJAX
Microsoft在异步编程模型尚未完全成熟之前,微软公司就开始了对早期ASP.NET的改进,希望借助Ajax技术使用户能有更好的体验。从ASP.NET 2.0开始,一方面继续使用同步编程模型处理服务器和客户端的通信,一方面引入了更加灵活的异步编程机制。
直到2007年微软公司才真正推出了具有Ajax风格的、方便的异步编程模型,这就是ASP.NET AJAX(注意,为了与其他Ajax技术区分,微软将其全部使用大写,并在前面加上了“ASP.NET”)。ASP.NET AJAX的正式命名为“ASP.NET AJAX Extensions”(ASP.NET AJAX扩展)和“Microsoft AJAX Library”(微软AJAX库)。
在Visual Studio 2005环境中ASP.NET AJAX Extensions还需要单独安装,而在Visual Stu-dio 2008之后的版本ASP.NET AJAX Extensions已被整合到了控件工具箱中。
Microsoft AJAX Library是客户端JavaScript库,它对核心JavaScript类型系统、基于JSON(JavaScript Object Notation)的网络层、JavaScript组件/控件模型及常用的客户端JavaScript辅助类等提供了跨平台的支持。
本章主要从ASP.NET AJAX基本控件和ASP.NET AJAX控件工具包两个方面介绍Ajax技术在ASP.NET开发中的应用。
6.2 ASP.NET AJAX的基本控件
在Visual Studio的控件工具箱中,包含ScriptManager、ScriptManagerProxy、UpdatePanel、UpdateProgress和Timer等ASP.NET AJAX控件,使用这些控件可以实现无须编写代码即可在应用程序中使用AJAX功能。
6.2.1 ScriptManager和ScriptManagerProxy控件
脚本管理器(ScriptManager)控件是ASP.NET AJAX的最底层支持,它提供了对客户端脚本的各种管理功能。该控件包含在Visual Studio工具箱的AJAX Extensions标签中,与其他标准控件一样,使用时直接将其拖动到页面中即可。ScriptManager虽然以控件的形式出现,但由于它是用来提供底层支持的,在程序运行期间不可见,故在页面设计时可将其放置在任何位置。
ScriptManagerProxy控件的作用与ScriptManager基本一致,但由于在一个页面中只能有一个ScriptManager(包含了所有脚本资源),如果把它放到母版页,而内容页又需要不同配置的话,则应在内容页中使用ScriptManagerProxy控件。
1.ScriptManager的常用属性和方法
要使用ASP.NET AJAX提供的各种功能,在页面中必须包含一个ScriptManager控件,通过该控件提供的各种属性、方法和事件可实现对客户端脚本进行各种复杂的管理。
ScriptManager控件的常用属性如表6-1所示。
表6-1 ScriptManager控件的常用属性
ScriptManager控件的常用方法如表6-2所示。
表6-2 ScriptManager控件的常用方法
2.使用ScriptManager控件注册客户端脚本
ScriptManager控件提供了注册客户端脚本的多种方法,主要应用于需要动态生成脚本的场合。所谓注册脚本,实际上就是通过在服务器端编写代码的方式编写客户端脚本,只不过这些脚本在将网页发送到客户端时,是通过ScriptManager控件将其添加到网页中的,其效果与直接在页面中编写脚本的效果完全相同。不同的是,写在页面中的脚本是静态的、不能变化的,而使用注册脚本的方法则可根据实际需要将不同的脚本动态地发送到客户端。
(1)使用RegisterClientScriptBlock方法
RegisterClientScriptBlock方法是一个静态方法,用于动态地向网页中添加客户端脚本块。该方法的重载形式有以下两种。
public static void ScriptManager.RegisterClientScriptBlock(Control control,Type type,string key,string script,bool addScriptTags)
或
public static void ScriptManager.RegisterClientScriptBlock(Page page,Type type,string key,string script,bool addScriptTags)
各参数的含义说明如下。
control:注册客户端脚本的控件名称。
page:注册客户端脚本的网页。
type:注册客户端脚本的控件类型,一般常用typeof()方法获取控件的类型名。
key:标识该脚本块的字符串,相当于普通控件的ID属性。
script:要注册的脚本块字符串,即脚本的内容。
addScriptTags:表示是否在脚本块中添加<script>和</script>标记。
例如,下列语句为使用第一种重载方式为命令按钮控件Button1注册的一段名为my-script1的脚本命令,该脚本使用户在单击按钮时能弹出一个信息框。
本例中由于脚本块已经包含了<script>和</script>标记,故将addScriptTags参数设置为false。
下列语句可以实现同样的效果。
ScriptManager.RegisterClientScriptBlock(Buttonl,typeof(Button),"myscriptl","alert(this is a test.′);",true);
测试上述脚本时可在网页中添加一个ScriptManager控件和一个按钮控件,并将上述语句添加到按钮的单击事件中,当用户单击按钮时即可弹出提示信息框。
(2)使用RegisterStartupScript方法
RegisterStartupScript()方法用于在UpdatePanel控件中注册启动时立即执行的JavaScript脚本块,是一种AutoRun类型的自启动脚本。类似于常用的<body onload="f()">中的f()函数。
该方法的重载方式有以下两种。
public static void ScriptManager.RegisterStartupScript(Control control,Type type,string key,string script,bool addScriptTags)
或
public static void ScriptManager.RegisterStartupScript(Page page,Type type,string key,string script,bool addScriptTags)
6.2.2 UpdatePanel控件
UpdatePanel控件是一个容器控件,它规定了ScriptManager控件的管理范围,同样是ASP.NET AJAX中非常重要的一个服务器控件。配合使用ScriptManager控件和UpdatePanel控件,程序员几乎无须编写任何JavaScript代码即可实现网页中位于UpdatePanel控件内各对象的局部更新。
1.UpdatePanel控件的常用属性
UpdatePanel控件常用的属性主要有以下几个。
(1)Triggers属性
Triggers属性表示可以导致UpdatePanel控件更新的触发器集合。在UpdatePanel控件的“属性”窗口中单击Trigger属性值设置栏中的“浏览”按钮 ,弹出如图6-1所示的对话框,单击“添加”按钮右侧的“▼”标记,可以看到触发器成员有AsyncPostBackTrigger和PostBack-Trigger两种。
图6-1 设置UpdatePanel控件的Trigger属性
AsyncPostBackTrigger用来指定某个服务器控件,并将该控件触发的服务器事件作为Up-datePanel控件的异步更新触发器。
PostBackTrigger用来指定在UpdatePanel控件中的某个服务器控件,该控件引发的回传将不采用异步回传方式,而是采用传统的整页回传。
在属性栏中单击ControlID栏,其右侧会出现一个 按钮,单击该按钮打开下拉列表框,其中列出了当前页面中所有可选控件的ID值。
AsyncPostBackTrigger属性栏中的EventName属性表示与触发器挂钩的事件,若未指定事件则只有在目标控件引起了回发时才引起UpdatePanel控件的更新。
(2)ChildrenAsTrigger属性
ChildrenAsTrigger属性为一个bool值,用来说明UpdatePanel控件的子控件引起的回发是否能导致UpdatePanel控件的更新。
(3)UpdateMode属性
UpdateMode属性表示UpdatPanel控件的更新模式,有Always和Conditional两个。其中Always表示无论有没有Trigger(触发器),任何控件引起的回发都将更新该UpdatePanel控件;Conditional表示只有当前UpdatePanel的Trigger或ChildrenAsTrigger属性为True时,当前UpdatePanel中控件引发的异步回传、整页回传或服务器端调用了Update()方法才会更新该UpdatePanel控件。
(4)ContentTemplate属性
ContentTemplate属性用来定义UpdatePanel包含的内容,在其内部可以声明其他服务器控件或HTML元素。需要说明的是,该属性只能在页面的“源”视图下使用,不能在“属性”窗口中进行设置。在可视化页面编辑环境中,只要将其他控件添加(拖动)到Up-datePanel控件中,系统将自动在“源”代码中添加必要的<ContentTemplate>和</Content-Template>标记。
例如,下列在“源”视图中书写的代码,可将一个按钮控件Button1和一个标签控件Label1放置在UpdatePanel1控件中。
2.页面的局部更新和条件更新
ScriptManager控件与UpdatePanel控件配合,可以在不必编写任何JavaScript代码的情况下实现页面的局部更新和条件更新。
(1)页面的局部更新
在页面中添加一个UpdatePanel控件,在其中添加一个下拉列表框DropDownList1和一个标签控件Label1。为DropDownList1添加若干个供选项,并设置其AutoPostBack属性为true,使之在选项改变时能引起服务器回发。在UpdatePanel控件的外部添加一个文本框控件,并将其TextMode属性设置为Password。
编写DropDownList1的选项改变事件代码如下。
程序运行后在密码框中输入一组任意字符,然后改变DropDownList1的选项。可以看到选项值显示在标签中,页面没有闪烁,而且密码框中输入的字符串也没有丢失。这就说明只有UpdatePanel1内的控件(DropDownList1和Label)更新了,但整个页面并未随之刷新。如果将DropDownList1和Label移出UpdatePanel1,再次运行程序时会发现DropDownList1的选项变化将导致整个页面的更新,密码框中已输入的字符串将丢失。
(2)条件更新
UpdatePanel控件的UpdateMode属性的默认值为Always,表示页面中任何一个控件引发的回发事件都将引起UpdatePanel内部区域所有控件的更新,无论该控件是否位于Up--datePanel区域内。这种方式称为“无条件更新”。
如果希望只有页面中某个或某几个控件的某个事件才能引起UpdatePanel区域更新,可设置UpdateMode属性值为Conditional,ChildrenAsTri-ger属性为fals,而后利用控件的Trig- ger属性来实现。也就是为UpdatePanel控件指定一个或多个“触发器”,这种方式称为“条件更新”。
【演练6-1】通过UpdatePanel控件的属性设置实现局部更新和有条件更新。
程序设计步骤如下。
(1)设计Web页面
新建一个ASP.NET网站,向页面中添加一个ScriptManager控件和一个UpdatePanel控件。在UpdatePanel内部添加一个标签控件Label1和3个按钮控件Button1、Button2、But-ton3。在UpdatePanel外部添加一个标签控件Label2。
(2)设置对象属性
设置UpdatePanel控件的UpdateMode属性为Conditional,ChildrenAsTrigger属性为False,使UpdatePanel中子控件引起的回发不能导致UpdatePanel控件的更新。
单击Trigger属性设置栏右侧的“浏览”按钮 ,在弹出的对话框中单击“添加”按钮,向UpdatePanelTrigger集合中添加两个AsyncPostBack成员,并设置它们的ControlID分别为Button1和Button2,EventName为Click,即指定Button1和Button2的Click事件为UpdatePanel的触发器,如图6-2所示。设置完毕后单击“确定”按钮。
(3)编写事件代码
1)页面载入时执行的事件代码如下。
图6-2 设置UpdatePanel控件的Trigger属性
2)按钮1被单击时执行的事件代码如下。
3)按钮2被单击时执行的事件代码如下。
4)按钮3被单击时执行的事件代码如下。
按<F5>键运行程序,分别单击3个按钮,可以看到“按钮1”和“按钮2”被单击时引起UpdatePanel的更新,而“按钮3”被单击时却没有任何反应。说明触发器的设置阻断了“按钮3”的Click事件,实现了UpdatePanel的有条件更新。
此外,可以看到无论单击哪个按钮,位于UpdatePanel外部的标签Label2的内容始终没有变化,也就是说更新是局部的,仅限于UpdatePanel控件内部。
如果将3个按钮控件移动到UpdatePanel控件之外,再次分别单击它们,可以看到“按钮1”和“按钮2”的效果不变,但单击“按钮3”时却引起了整个页面的刷新,自然两个标签的内容也被更新。这是因为位于UpdatePanel控件之外的“按钮3”已不再是其子控件了,单击时自然就引起了整个页面的回发。
从前面的例子中可以看到,无论是有条件更新还是无条件更新,都会更新整个UpdatePanel中的内容。如果页面中的所有元素全部放在同一个UpdatePanel控件中,自然就失去了局部更新的意义。因此,在实际应用中,在一个页面中通常包含有多个UpdatePanel控件,将页面划分为若干个不同的更新区域,每个区域设置专门的触发器,并将不需要更新的内容放置在UpdatePanel之外。这样一来每次需要更新的范围即可大大缩减,使网页的反应速度更快。
6.2.3 UpdateProgress控件
UpdateProgress控件可以与UpdatePanel控件配合使用,在UpdatePanel内容进行更新时通过该控件显示一些提示信息,这些信息可以是一段文字、传统的进度条或一段动画等。当更新结束后,提示信息自动消失。UpdateProgress控件主要用在更新数据量较大,需要等待一段时间的场合。更新时显示提示信息或动画,可以避免用户操作后页面较长时间无反应的尴尬,如经常在计算机屏幕上看到的不停翻转的“沙漏”或手机屏幕上“旋转的小圆圈”等。
UpdateProgress控件的常用属性有AssociatedUpdatePanel、DisplayAfter、DynamicLayout和ProgressTemplate等。
1.AssociatedUpdatePanel属性
AssociatedUpdatePanel属性用于确定UpdateProgress控件与哪个UpdatePanel控件关联,如果设置了该属性值,则只有在被关联的UpdatePanel中发生更新时才会显示预设的提示信息。AssociatedUpdatePanel属性的默认值为空,表示页面中所有的UpdatePanel发生更新时都会显示提示信息。
2.DisplayAfter属性
DisplayAfter属性主要用于设定UpdateProgress控件的延迟时间(以毫秒为单位的时间间隔)。
在实际应用中,客户机的配置高低、UpdatePanel更新数据量的多少都会影响更新速度。如果更新速度较快,会出现UpdateProgress提示信息一闪而过的现象,起不到提示作用。这时可以考虑使用DisplayAfter属性设置一个等待时间,使提示信息的出现有一个用户尚能接受的延时。如果更新在这段时间内已经完成,则提示信息将不再显示。
3.DynamicLayout属性
DynamicLayout属性用来决定在加载页面时是否为UpdateProgress控件的提示信息动态分配页面空间。默认值为true,表示设计时无须为提示信息预留显示位置,需要显示提示信息时由系统动态分配其显示位置。如果将该属性设置为false,在没有显示提示信息时UpdateProgress的预留位置处会出现一个空白块,设计时应特别注意。一般情况下,推荐使用该属性的默认值true,由系统动态地分配提示信息显示位置。
4.ProgressTemplate属性
ProgressTemplate属性主要用来显示UpdateProgress控件所定义的提示信息。在初始化UpdateProgress控件时必须设置该属性,否则应用程序将出现错误。
将UpdateProgress控件添加到页面后,可以直接在设计视图中将提示文字信息书写在UpdateProgress控件内,如图6-3所示。
图6-3 在设计视图中添加提示信息
如果希望用动画、图片等显示提示信息,可在源视图中按照以下代码所示,将适当的标记语言语句添加到<ProgressTemplate>和</ProgressTemplate>标记之间,或在设计视图中向UpdateProgress控件中添加其他控件。
6.2.4 Timer控件
Timer控件,也称为“定时器”控件,用于周期性地自动触发Tick事件,也就是说用Timer控件可以实现周期性执行某段代码的功能。例如,页面的定时刷新、图片自动播放和在线考试等需要计时的应用场合。
1.Timer控件的常用属性和事件
Timer控件的常用属性有Interval和Enable。常用的事件为Tick。
(1)Interval属性
Interval属性用于设置页面向服务器发送回传的、以ms(毫秒)为单位的时间间隔,默认值为60000ms。
使用Timer控件执行页面自动更新操作时应注意,不能将Interval值设置得太小。如果设置不当,可能出现上一个更新尚未结束,一个新的更新又被启动,这将导致未完成的更新自动取消。此外,Interval值设置得过小将导致更新频繁发生,这无疑将增加服务器的负担。一般应根据需要将其设置为能满足需要的最大值。
(2)Enable属性
Enable属性与其他标准控件的Enable属性相同,用来决定Timer控件是否可用,若将该属性设置为false则表示Timer控件被禁用,默认值为true。
(3)Tick事件
Tick事件是Timer控件周期性触发的事件,写在该事件过程中的代码能被应用程序周期性地自动执行。
Timer控件可以放置在UpdatePanel控件的内部或外部。如果放在内部,Interval属性设定的时间间隔是从回传页面后开始计算的。例如,将Interval属性设置为60000,而回传需要的时间为3s,那么两次回传的时间间隔就是63s。如果Timer控件放置在UpdatePanel控件之外,将导致整个页面周期性刷新,而且时间间隔是从回传到服务器时就开始计算的。例如,将Interval属性设置为60000,回传需要的时间为3s,则两次回传发生的间隔为60s,用户看到的刷新间隔则是57s。
2.使用Timer控件
【演练6-2】在一些网站的用户注册页面中常看到这样的设置,用户填写了注册数据后,必须选择接受网站的一些规定,并观看该规定一段时间(如10s)后才能提交数据,完成注册操作。使用ScriptManager控件、UpdatePanel控件和Timer控件设计一个具有上述功能的网页。
具体要求如下。
1)网站包括Default.aspx和Welcome.aspx两个页面,Default.aspx加载时显示一些文字和一个不可用的命令按钮(Enable属性为false),如图6-4所示。经过10s后,按钮可用,单击该按钮可跳转到Welcome.aspx页面,如图6-5所示。
2)程序能限制用户绕过Default.aspx页面,通过URL直接调用Welcome.aspx页面。
3)为增加程序的界面友好性,在用户等待过程中,按钮上显示一个倒计时的数字进度提示。
图6-4 等待10秒
图6-5 等待期结束
程序设计步骤如下。
(1)设计Web页面
新建一个ASP.NET空网站,向网站中添加一个Web窗体页Default.aspx。向页面中添加一个ScriptManager控件和一个UpdatePanel控件。向UpdatePanel控件中添加一些文字、一个按钮控件Button1、一个定时器控件Timer1和一个隐含字段控件HiddenField1。适当调整各控件的大小及位置。设置Timer1的Interval属性值为1000(1s)。
(2)编写程序代码
1)Default.aspx页面载入时执行的事件代码如下。
2)计时器激活时执行的事件代码如下。
3)Welcome.aspx页面载入时执行的事件代码如下。
需要说明的是,本例中使用HiddenField控件保存了用户是否通过的敏感信息,这在实际应用中并不可取(这里仅仅是为了说明控件的使用方法)。因为保存在HiddenField控件中的数据是以Base64编码保存在页面中的(可以在浏览器中查看源代码得到),Base64编码的字符串可以保证没有任何非法的HTML字符。但是,Base64位编码可以被转换回明码字符串。也就是说,用户可以借助Base64编辑器看到保存在HiddenField控件中的内容。
6.3 ASP.NET AJAX控件工具包
ASP.NETAJAX是一种开源的网页设计技术。它以控件的形式出现,几乎无须编写任何JavaScript代码就可以实现Web窗体与服务器间的异步传递。除了美国微软公司在Visual Studio中提供的AJAX扩展基本控件外,其他开发人员也可以在此基础上开发新的控件。ASP.NET AJAX控件工具包(ASP.NET AJAX Control Tookit,目前最高版本为15.1.4)就是由微软公司和其他开发人员共同推出的又一组应用于ASP.NET AJAX环境的AJAX控件。该工具包目前已包含几十个功能强大的控件,开发人员可以像使用ASP.NET标准控件那样使用这些AJAX控件。
6.3.1 安装ASP.NET AJAX控件工具包
ASP.NET AJAX Control Toolkit并没有包含在Visual Studio 2015中,使用前需要从Inter-net中下载并安装整合到Visual Studio中。需要说明的是,控件工具包的更新频率非常快,不断有新的控件或功能被添加进来,而且工具包的官方下载地址也有可能变化。目前ASP.NET AJAX Control Toolkit安装包的官方下载地址为:http://ajaxcontroltoolkit.codeplex.com/releases。在浏览器中,输入网址进入如图6-6所示的网站后,单击导航栏DOWNLOADS,在右侧OTHER DOWNLOADS栏中可以看到最新的工具包版本,以及该版本的发布和更新日期。本例中使用的ASP.NET AJAX Control Toolkit v15.1.4发布于2015年10月26日,最后更新于2016年3月11日。
图6-6 下载ASP.NET AJAX Control Toolkit v15.1.4
退出Visual Studio,运行下载的安装包程序,安装进程结束后再次启动Visual Studio可以看到工具箱中多出了一个名为AJAX Control Toolkit v15.1的选项卡,其中包含有51个ASP.NET AJAX扩展控件,如图6-7所示。
需要说明的是,ASP.NET AJAX Control Toolkit中包含的控件分为“AJAX控件”和“扩展控件”两类。前者与标准控件相似,可以单独使用;而后者则需要附加在其他标准控件上,不能单独使用。顾名思义,扩展控件的作用就是给Web标准控件添加一些新的扩展功能,所以扩展控件的名称均以Extender(扩展器)结尾。
ASP.NET AJAX Control Toolkit安装后,Visual Studio会自动监控添加到Web窗体页中的标准控件,并为其添加一个“任务”菜单。选中一个标准控件后,控件的右上角会出现一个 标记,单击该标记,打开如图6-8所示的“任务”菜单。选择“添加扩展程序”选项,弹出如图6-9所示的“扩展程序向导”对话框,其中列出了所有对当前控件可用的扩展功能。选择完毕后单击“确定”按钮。为标准控件添加了扩展之后,Visual Studio会将扩展控件的相关属性与控件原有属性整合到“属性”窗口中,如图6-10所示。
图6-7 新增AJAX控件
图6-8 任务菜单
图6-9 “扩展程序向导”对话框
图6-10 整合后的“属性”窗口
6.3.2 使用ConfirmButtonExtender控件弹出确认对话框
在许多应用程序中,经常需要执行删除数据的操作,为了保证操作不是因用户误操作引起的,通常在删除重要数据前会要求用户进行确认。ASP.NET AJAX控件工具包中的Con-firmButtonExtender控件是一个扩展控件,可以为Button、LinkButton和ImageButton等控件添加弹出确认对话框的功能。
需要强调的是,使用任何ASP.NET AJAX控件都必须在Web窗体页中添加一个Script-Manager控件,作为JavaScript脚本的底层管理。
1.ConfirmButtonExtender控件的常用属性
ConfirmButtonExtender控件是一个不能单独使用的扩展控件,需要附加在Button、LinkButton和ImageButton等标准控件之上,为其提供弹出确认对话框的功能。其常用的属性有以下几个。
(1)ConfirmText属性
该属性用于设置弹出确认对话框时,对话框中显示的确认信息文本。
(2)OnClientCancel属性
该属性用于设置当用户单击对话框中的“取消”按钮时执行的代码。默认值为空,表示不执行任何操作。
(3)TargetControlID
该属性用于指定ConfirmButtonExtender控件为哪个标准控件提供弹出确认对话框的扩展功能。
上述属性的值既可以在属性窗口中设置,也可在源视图中编写代码设置,但不能在事件过程中通过代码进行设置或修改,这一点与标准控件的属性设置方法有所不同。
2.ConfirmButtonExtender控件使用示例
【演练6-3】ConfirmButtonExtender控件使用示例。程序启动后显示如图6-11所示的页面,当用户单击“删除数据”按钮时弹出如图6-12所示的确认删除对话框。如果用户单击“确定”按钮,将清除显示在标签中的文字;单击“取消”按钮则不执行“删除”操作。
图6-11 单击“删除数据”按钮
图6-12 确认删除对话框
程序设计步骤如下。
(1)设计Web页面
新建一个ASP.NET空网站,向网站中添加Web窗体Default.aspx。向窗体中添加一个脚本管理控件ScriptManager1、一个标签控件Label1和一个按钮控件Button1。
(2)设置对象属性
参照前面介绍过的方法,为命令按钮控件Button1添加了ConfirmButtonExtender扩展功能后,其“属性”窗口中多出了一个名为Button1_ConfirmButtonExtender的属性集合,设置其中的ConfirmText属性为希望显示到对话框中的提示信息文本,如本例的“数据将被删除,请确认!”。
(3)编写事件代码
1)Default.aspx窗体载入时执行的事件代码如下。
2)“删除数据”按钮被单击时执行的事件代码如下。
6.3.3 使用FilteredTextExtender和TextBoxWatermarkExtender扩展控件
FilteredTextExtender和TextBoxWatermarkExtender都是TextBox控件的扩展,前者可对用户通过TextBox输入的文本内容进行过滤,后者可在TextBox内容为空时显示输入提示。
1.FilteredTextExtender扩展控件的常用属性
FilteredTextExtender扩展控件的常用属性如表6-3所示。
表6-3 FilteredTextExtender的常用属性及说明
2.TextBoxWatermarkExtender的常用属性
TextBoxWatermarkExtender扩展控件的常用属性有WatermarkText和WatermarkCssClass。
WatermarkText属性用于设置文本框内容为空时,文本框内显示的文本内容。通常用于显示输入指导。
WatermarkCssClass属性用于指定文本框内容为空时的外观样式类,如文字的样色、文本框的边框颜色和样式、背景色等。
3.FilteredTextExtender和TextBoxWatermarkExtender使用示例
【演练6-4】使用FilteredTextExtender限制用户只能在文本框中输入数字。
新建一个ASP.NET空网站,向网站中添加一个Web窗体页面Default.aspx。向页面中添加一个脚本管理控件ScriptManager1和一个文本框控件TextBox1。为TextBox1添加FilteredT-extExtender扩展和TextBoxWatermarkExtender扩展。
在“属性”窗口中设置FilteredTextExtender下的FilterType属性为Custom,FilterMode属性为ValidChars,ValidChars属性为“1234567890.”;设置TextBoxWatermarkExtender的Wa-termarkText属性为“只能输入数字和小数点”,设置WatermarkCssClass属性值为“style1”。
切换到Default.aspx的源视图,在<head>…</head>之间为style1编写以下代码。
运行程序,可以看到文本框内容为空时显示出了预设的提示文本。当单击文本框时,提示自动消失。在文本框中输入任何非数字字母或符号时,系统会自动将其屏蔽。只有数字和小数点才能被正常输入。
需要说明以下两点。
1)一个Web标准控件可以附加多个ASP.NET AJAX扩展控件。如本例就为TextBox附加了FilteredTextExtender和TextBoxWatermarkExtender两个扩展。
2)FilterTextExtender只能作为TextBox输入验证的补充,通常用于防范用户无意间输入了错误的数据。在重要环境中(如SQL注入防范)不能用它取代输入验证。因为恶意的用户可以篡改下载到本地的Web页面,甚至可以采用禁用JavaScript的方法使字符过滤失效。
测试和思考:
执行IE主菜单中的“Internet选项”命令,在弹出的对话框中选择“安全”选项卡,单击“自定义级别”按钮,在“脚本”栏中将“活动脚本”设置为“禁用”。设置完毕后,再次运行本程序会有怎样的结果?
将IE恢复为初始状态后再次运行本例,在IE窗口空白处右击,在弹出的快捷菜单中选择“查看源”命令,打开“F12开发人员工具”窗口。认真阅读其中的HTML代码,能看到设置的字符过滤器源代码吗?能修改吗?修改后能运行吗?修改后字符过滤还有效吗?
6.3.4 使用AsyncFileUpload控件实现文件上传
AsyncFileUpload是一个独立的ASP.NET AJAX控件,用于实现文件的异步上传。用户可以在文件上传期间继续和页面交互,但是继续的操作不能引起服务器端回发或跳转到其他页面,否则会中断文件上传。
1.AsyncFileUpload控件的常用属性、事件和方法
AsyncFileUpload控件的常用属性及说明如表6-4所示,常用事件及说明如表6-5所示。
表6-4 AsyncFileUpload的常用属性及说明
在实际应用中,经常使用AsyncFileUpload控件的PostedFile对象提供的ContentType和ContentLength两个只读属性来获取文件的类型和大小。
表6-5 AsyncFileUpload的常用事件及说明
AsyncFileUpload控件最常用的方法是SaveAs,用于将添加到控件的文件上传到服务器指定的文件夹中。
2.AsyncFileUpload控件使用示例
【演练6-5】使用AsyncFileUpload控件实现图片上传。要求只能上传jpg格式的文件,文件大小不能超过2MB。程序启动时的界面如图6-13所示;正在上传时显示如图6-14所示的界面;图片成功上传后能立即在图片框中显示出来,如图6-15所示。
图6-13 运行时的初始界面
图6-14 正在上传
图6-15 上传结束
程序设计步骤如下。
新建一个ASP.NET空网站,向网站中添加Web窗体Default.aspx。向窗体中添加一个脚本管理控件ScriptManager1、两个图片框控件Image1(用于显示上传后的图片)和Image2(用于呈现表示正在上传的动画图片),以及一个异步上传控件AsyncFileUpload1。程序界面设计如图6-16所示。文件类型错误或超过规定大小将弹出如图6-17所示的信息框。在网站文件夹下新建一个upload文件夹,用于保存上传的图片文件。新建一个images文件夹,并将准备好的动画图片复制到其中。
设置AsyncFileUpload1的OnClientUploadComplete属性为C_UploadComplete,指定上传完成时执行的客户端JavaScript脚本函数。
图6-16 程序界面设计
图6-17 文件类型或大小超出限制
1)Default.aspx页面载入时执行的事件代码如下。
2)AsyncFileUpload控件上传完成时执行的事件代码如下。
3)切换到Default.aspx的源视图,在<body>…</body>之间编写下列JavaScript客户端脚本函数代码,供AsyncFileUpload控件上传结束后自动调用。
说明:上述JavaScript脚本函数以刷新页面的方式,配合Page_Load事件中显示图片的代码,实现了上传后的图片立即显示。这种方法虽然简单,但引起页面刷新毕竟还是略显不足。实际应用中应通过该函数操作Image1,使之显示上传完成的图片,而不引发页面刷新,从而给用户以最佳的体验。
6.3.5 使用CalendarExtender和AutoCompleteExtender扩展控件
CalendarExtender扩展控件用于为TextBox控件提供一个格式化日期输入扩展,单击文本框时将弹出一个日期(年、月、日)选择框,用户选择后TextBox中自动显示格式化后的日期值。AutoCompleteExtender扩展控件用于为TextBox提供一个类似百度搜索栏的自动匹配选择列表,使用户可以用选择的方式替代全文输入。与所有扩展控件一样,这两个控件也需要在页面中添加ScriptManager控件以提供底层支持。
1.使用CalendarExtender扩展控件
计算机中不同的设置会导致日期格式的不同,在Web页面中需要输入日期值时常会导致出现格式错误。CalendarExtender扩展控件附加在TextBox控件之后,可以为用户提供一个标准化的日期输入方式。
在添加了ScriptManager控件的Web页面的设计视图中选中TextBox控件,通过“任务”菜单为其添加CalendarExtender扩展。为了使CalendarExtender能以中文方式显示日期,需要在页面源视图ScriptManager控件的声明代码中,添加如下所示的属性设置。
<asp:ScriptManager ID="ScriptManager1"runat="server"EnableScriptGlobalization=trueEnableScriptLocalization=true></asp:ScriptManager>
CalendarExtender扩展控件的常用属性有Format(用于设置最后显示到文本框中的日期格式)、DaysModeTitleFormat(用于设置显示到最上方标题中的日期格式)和ToDaysDateFor-mat(用于设置最下方Today的日期格式)。
本例设置DaysModeTitleFormat属性为“yyyy年M月”,设置ToDaysDateFormat属性为“yyyy-M-d”,设置Format属性为“yyyy-M-d”。
如果希望月、日以两位数显示,可使用类似“yyyy-MM-dd”的格式符进行设置。
程序运行后,单击文本框,将打开如图6-18所示的日期选择器。用户选择完毕后,系统能自动将对应的日期标准格式显示到文本框中。
2.使用AutoCompleteExtender扩展控件
AutoCompleteExtender扩展控件需要Web服务(WCF或Web Service)的支持才能实现。Web服务在程序运行过程中为Auto-CompleteExtender提供所需的数据集和匹配筛选,数据集的来源可以是数据库、数据文件或数组对象等。
图6-18 日期选择器
AutoCompleteExtender的常用属性如表6-6所示。
表6-6 AutoCompleteExtender的常用属性及说明
【演练6-6】使用AutoCompleteExtender扩展控件,配合Windows通信基础(Windows Communica-tionFoundation,WCF)服务,为文本框添加匹配自动完成功能。如图6-19所示,程序运行后页面中显示一个文本框,用户在其中输入文字后,系统能自动从预设的数据集中匹配出前几个字符相同的数据,并以列表的方式呈现。用户可以使用键盘或鼠标,通过选择完成输入。
图6-19 文本框的自动完成功能
程序设计步骤如下。
1)新建一个ASP.NET空网站,向网站中添加一个Web窗体Default.aspx。向窗体中添加一个脚本管理控件ScriptManager1,添加说明文字和一个文本框控件TextBox1。通过文本框的“任务”菜单为其添加AutoCompleteExtender扩展。
2)在解决方案资源管理器中右击网站名称,在弹出的快捷菜单中选择“添加”→“添加新项”命令,在弹出的如图6-20所示的“添加新项”对话框中选择“WCF服务(支持Ajax)”选项,指定服务文件名后单击“添加”按钮,系统将自动创建一个空白的服务代码文件,并将其保存到App_Code文件夹中。
图6-20 添加支持Ajax的WCF服务
3)编写WCF服务代码如下(App_Code文件夹下的Service.cs)。
4)WCF服务代码编写完毕后,回到Default.aspx的设计视图,选中TextBox1,在“属性”窗口中设置其CompletionInterval属性为100,表示用户输入文字0.1s后开始匹配;设置TextBox1的MinimumPrefixLength属性为1,表示用户输入1个字符后就开始匹配;设置ServiceMethod属性为UnitList(名称一定要与WCF中相同);设置ServicePath属性为Serv-ice.svc,表示WCF服务文件在网站根目录中,名为Service.svc。
设置完上述属性后,运行程序可以看到文本框已具有了自动完成功能,但出现的列表与文本框之间有一个距离,不是很美观。若需要调整,可在Default.aspx的源视图中,在“头标记”<head>…</head>之间添加下列样式设置。
请思考以下两个问题。
1)一个WCF服务能否为多个不同的文本框提供自动完成功能?
2)一个WCF服务能否根据实际需要,为同一文本框提供内容不同的自动完成功能?
6.4 实训——设计一个限时在线考试系统
6.4.1 实训目的
1)掌握ASP.NET AJAX基本控件的属性设置及使用方法。进一步理解页面局部更新的重要性。了解ASP.NET AJAX扩展控件的使用方法。
2)掌握Timer控件的主要属性、方法和事件,能设计出具有定时功能的应用程序。
6.4.2 实训要求
设计一个能限制时间的在线考试系统,该系统具有以下几个功能。
1)系统支持最多100道的单选题(4选1)。
2)考试题目存储在单独的文本文件内(App_Data/test.txt)。如图6-21所示,每题以题目内容、正确答案、4个选项为顺序逐行书写。
3)自动生成如图6-22所示的考试成绩表,存放在App_Data/result.txt文件中。
4)考生访问网站时首先看到的是如图6-23所示的登录界面,在输入“姓名”和“准考证号”后单击“开始考试”按钮,系统首先对用户输入的“姓名”及“准考证号”的合法性进行检测,要求“姓名”和“准考证号”不得为空;准考证号必须由6位数字组成,且考生不是重复考试(成绩表中没有该准考证号的记录)。若未通过检测将显示相应的出错提示信息。
图6-21 试题内容
图6-22 自动生成的考试成绩表
通过检测后即可进入如图6-24所示的答题界面。在答题界面的右上角始终显示一个倒计时的“剩余时间”指示。
图6-23 登录系统
图6-24 答题界面
5)考生答题结束后,单击答题页面下方的“提交试卷”按钮,屏幕上将显示如图6-25所示的本次考试的成绩,并将该成绩保存到App_Data/result.txt文件中。
图6-25 显示考试成绩
页面HTML代码及服务器端事件代码请读者自行完成。