----------http://book.csdn.net/bookfiles/376/10037614187.shtml
15.3 ASP.NET AJAX Extension简介
ASP.NET AJAX Extension是微软即将推出的AJAX框架的名称,之前的开发代号为Atlas。到目前为止,它包含3个部分,它们分别是ASP.NET AJAX Extensions、AJAXControlToolkit和Feature Pack。
下面就对ASP.NET AJAX Extension进行介绍。由于ASP.NET AJAX还没有正式发布,所以本节所讲的内容还有可能在正式版中发生变化,本节的内容基于ASP.NET AJAX的RC版本。
15.3.1 ASP.NET AJAX框架的由来
ASP.NET提出了Web Form这个概念,让Web开发向桌面程序开发的模式靠拢,让开发人员可以通过拖拉控件就能完成很大部分的编程任务。Web Form让页面形成了这样的程序,页面的HTML代码控制界面,服务器端的代码控制程序的逻辑。当用户有操作使页面的状态发生了变化,页面就会向服务器提交操作的信息,然后服务器处理信息,发送处理的结果。这个结果通常是产生新的界面,也就是说页面是由服务器端代码来控制的。服务器和客户端之间的通信依赖于回送(PostBack)。PostBack会提交Form表单中的输入控件的信息,其中包含了视图状态信息。由于PostBack一般是同步的,客户端页面一旦提交,就必须等待服务器的处理结果,然后用户才能继续操作。如果页面的功能较多,那么视图状态包含的数据就比较多,用户不得不在操作以后等上一小段事件之后才能继续,造成不良的用户体验。这也让Web Form虽然开发模式与windows程序类似,但实际使用效果相差甚远。
那么AJAX又有什么问题呢?与ASP.NET的Web Form不同,AJAX模式的应用程序以每个页面为一个应用程序,界面和逻辑的代码都包含在同一个页面中,而服务器的功能在于提供数据。创建这样一个Web应用程序并不那么简单。必须使用JavaScript来编程,必须理解DOM以及DOM在不同浏览器之间的细小差异。同时,JavaScript语言虽然也支持面向对象的一些特性,可是它并不优雅和完善。另外JavaScript是一个弱类型的语言,缺乏.NET为开发人员提供的各种高级功能。简单来说,创建AJAX程序需要JavaScript和DOM的专家,然后按照新的应用程序模式在新的平台上创建应用程序,风险很大。
以上就是为什么要推出ASP.NET AJAX Extension的主要原因。ASP.NET AJAX是一种新的ASP.NET应用程序开发框架。它把客户端的AJAX脚本框架与ASP.NET整合到了一起。使用ASP.NET AJAX Extension创建ASP.NET应用程序让开发者感觉不到在编写AJAX程序,几乎与编写ASP.NET应用程序一样。这意味着使用ASP.NET AJAX Extension框架开发应用程序,既可以是采用AJAX的程序的运行方式,又可以充分利用ASP.NET所能带来的便捷。
15.3.2 ASP.NET AJAX框架的组成
正如本节开头所提到的,目前ASP.NET AJAX框架由3个部分组成,ASP.NET AJAX Extensions、AJAXControlToolkit和Feature CTP。
ASP.NET AJAX Extensions包含了ASP.NET AJAX框架的服务器端引擎和组件,以及核心的客户端脚本库。
1.ASP.NET AJAX框架的客户端脚本库
ASP.NET AJAX客户端脚本库与服务器端组件库可以分开使用,并不强制性要使用在同一个项目中。客户端脚本库是由JavaScript文件(.js)组成的,因此它提供了跨浏览器和跨平台的可能性。客户端脚本库提供如下的功能。
(1)浏览器兼容层:它提供跨越大多数主流浏览器的兼容性支持,使ASP.NET AJAX的客户端脚本能在不同的浏览器上顺利运行,从而使开发人员不必再去编写针对特定浏览器的代码。
(2)ASP.NET AJAX框架的核心类库:提供了一套完整的以JavaScript编写的类库,包括了命名空间、事件处理、继承、数据类型和序列化等一系列的面向对象的特性。这些面向对象的特性将极大的帮助开发人员编写高质量、可维护、可复用的程序。
(3) ASP.NET AJAX框架的基础类库:包括了一些开发人员必须的工具,如String Builder、调试器、Timer和Tracing功能。
(4)网络通信库:这一层管理与其他网络应用的通信和远程异步调用。该层封装了XMLHttpRequest对象,对开发人员隐藏了XMLHttpRequest调用的复杂性。开发人员不会知道,自己正在使用XMLHttpRequest对象。
(5)用户界面层:用户界面层为客户端提供了如行为描述的能力、ASP.NET AJAX声明式语法、UI组件和数据绑定。
2.ASP.NET AJAX框架服务器端组件库
如果仅仅只有客户端脚本,ASP.NET AJAX框架无法与ASP.NET紧密地整合,又如何能充分利用到ASP.NET现有的功能呢?因此,有了ASP.NET AJAX框架服务器端组件库。ASP.NET AJAX框架的服务器端组件提供服务器端组件、服务和控件,并且可以整合到客户端脚本中去。
(1)通过Web Service提供ASP.NET的Profile、成员管理、角色、个性化以及全球化和本地化之类的支持。
(2)ASP.NET AJAX框架服务器端控件:在本书的前面,对服务器控件的开发进行了一些讲解,服务器控件会输出自身所需要的外观和脚本。ASP.NET AJAX框架的服务器控件也一样,只不过它们将会输出ASP.NET AJAX框架特定的客户端脚本。ASP.NET AJAX框架的服务器控件包括了许多常见的控件,如Button、TextBox、CheckBox、hyperlink之类的控件。它们与现有的ASP.NET服务器控件的使用方法基本相同。
(3)以用ASP.NET AJAX服务器控件输出的客户端脚本产生客户端组件的一些行为。
ASP.NET AJAX ControlToolkit则包含了大量ASP.NET AJAX风格的服务器端控件。它包含了一个控件库,提供了一套AJAX风格的ASP.NET AJAX框架的专用服务器端组件。控件包含了诸如自动完成文本框、ListView、动画组件等。随着ASP.NET AJAX框架逐渐接近正式版,控件库中包含的控件还会越来越多。这些控件相当的酷,相信凭借它们就能吸引很多人的目光。如果需要在项目中采用这些控件,则需手动添加对AspNetControlToolkit.dll的引用。
ASP.NET AJAX Feature Pack包含了一些还没有最终决定是否加入ASP.NET AJAX框架的特性,其中一些特性也相当的有趣,喜欢尝鲜的朋友可以进行试用。
最后用一个图来说明ASP.NET AJAX的整个构架,如图15-10所示。
图15-10 ASP.NET AJAX构架图
ASP.NET AJAX最终将会被整合到ASP.NET 2.0,以及之后的版本中。
15.3.3 ASP.NET AJAX的获取和安装
如果从来没有安装过ASP.NET AJAX组件,那么可以从ajax.asp.net或者是download. microsoft.com网站上获得ASP.NET AJAX安装包的下载路径。下载好ASP.NET AJAX安装包以后,双击安装包启动安装。安装非常简单,只需要一直点击“下一步”或者“Next”就可以了。ASP.NET AJAX会被默认安装到“C:/Program Files/Microsoft ASP.NET/ASP.NET 2.0 AJAX Extensions”路径下。
安装成功以后,“C:/Program Files/Microsoft ASP.NET/ASP.NET 2.0 AJAX Extensions”路径下包含了System.Web.Extension.dll程序集和客户端脚本库(ScriptLibrary)。
15.3.4 ASP.NET AJAX的客户端脚本库
通过图15-10和之前的介绍,可以得知,ASP.NET AJAX框架的核心是在客户端的脚本库,而服务器端的组件是为了给客户端提供更多的功能才出现的。本节就来对客户端脚本库的具体功能进行一些介绍。
客户端脚本库是由一系列的JavaScript文件(.js)文件组成的。通过这些JavaScript文件,ASP.NET AJAX框架构建了一个面向对象的类库。类库包含的功能,在15.3.2小节中已经提到,这里用一个图进行再次的说明,如图15-11所示。
下面对脚本库中的每个文件的功能进行说明。脚本库存放在[安装盘]:/ Program Files/Microsoft ASP.NET/ ASP.NET 2.0 AJAX Extensions/v1.0.61025/ MicrosoftAjaxLibrary/路径下,分为调试版和分发版。它们的功能一致,不同的是调试版增加了一些方便调试的语句;另外,发布版本去掉了所有的不必要的空格和换行,无法阅读,所以为了学习和研究ASP.NET AJAX的功能,应该使用调试版本的代码。脚本库包含3个文件,下面对每个文件的作用进行简要说明。
(1)MicrosoftAjax.js—MicrosoftAjax.js包含了全部的ASP.NET AJAX客户端功能。MicrosoftAjax.js包含了客户端脚本库的面向对象扩展,基本的类型,控件和功能。这些脚本已经为主流的浏览器提供了良好的兼容性。
(2)MicrosoftAjaxTimer.js—MicrosoftAjaxTimer.js提供了一个AJAX风格的客户端的定时器。
(3)MicrosoftAjaxWebForms.js—这个脚本文件中定义了管理ASP.NET页面进行异步HTTP请求的一系列方法和事件,覆盖了整个请求的生命周期。包括重要的PageRequestManager对象。
15.3.5 创建ASP.NET AJAX网站
安装了ASP.NET AJAX Extension程序包以后,就可以在Visual Studio 2005中创建ASP.NET AJAX应用程序了。打开Visual Studio 2005,选择新建一个Web站点,在站点类型的选择窗口中,选择“ASP.NET AJAX-Enabled Web Site”,如图15-12所示:
图15-12 新建ASP.NET AJX Web Site
选择了应用程序的路径后,点击确定,站点就会被创建。ASP.NET AJAX站点和普通的ASP.NET站点没多少区别,不过在引用中多了System.Web.Extension.dll的引用,如图15-13所示:
图15-13 ASP.NET AJAX站点
打开Default.aspx页面,页面Body标签内的代码如下所示:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
</div>
</form>
<script type="text/xml-script">
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<references>
</references>
<components>
</components>
</page>
</script>
项目创建时,自动在Form标签内增加了一个asp:ScriptManager组件。ScriptManager组件相当重要,如果希望在某个页面中使用ASP.NET AJAX的功能,那么必须添加一个且最多一个ScriptManager组件。当添加了ScriptManager之后,客户端脚本文件就会被加入到客户端的下载内容中。
ScriptManager 是一个协调者,它自身维护了一些常用的状态,并会根据状态来切换 Altas 引擎的工作机制。最常使用的是 EnablePartialRendering属性,AuthenticationService-Path和ProfileService-Path属性。
EnablePartialRendering 属性决定是否启用局部重绘的模式。传统的ASP.NET的Post Back 模式页面,在用户提交时会重绘整个页面,并明显导致浏览器闪烁。而在基于 AJAX 技术的 ASP.NET AJAX 框架中,可以通过 UpdatePanel 标签指定需要重绘的局部。这样,页面在处理请求时,会首先根据 ScriptManager.IsInPartialRenderingMode 属性判断是否在重绘模式中。如果在重绘模式,则仅仅将需要重绘的 UpdatePanel 内容,返回给客户端浏览器,并由ASP.NET AJAX框架 自动进行内容的更新。通过这种模式,使用者可以在对代码几乎无修改的情况下,直接享受到AJAX带来的客户端用户体验的提升。在RC版本的ScriptManager中,默认情况下,这个属性的值是“true”。
AuthenticationService-path属性可以指定一个用来验证用户身份的Web服务的地址。然后ASP.NET AJAX框架就可以通过这个Service来判断用户是否合法。
ProfileService-path属性则是为系统提供了用户档案的支持,通过指定Profile Web服务,可以管理用户的档案。
当在服务器页面加入了ScriptManager组件以后,用IE访问页面,生成的HTML页面中就会有下面类似的代码:
<script src="/AtlasDemo/ScriptResource.axd?d=2AltBMHfucJWheAkBrxmwj9t3l9jgCzZu5HWLh7gpTFYbTWMa__2MoanbRowpuU-owo_IryP5uO9VmsnEgyTpAD-v4dOIKwUGhZfYCTIxNg1&t=633025108181875000" type="text/javascript"></script>
如果想要使用ASP.NET AJAX Feature CTP所提供的其他扩展功能,例如在页面上实现的拖拉功能、特殊的视觉效果或者Web Part组件的支持等,那么需要引用对应的客户端脚本。下面的代码示例了如何在页面中引用这些脚本:
<asp:ScriptManager id="scriptManager1" runat="server">
<scripts>
<asp:scriptreference scriptname="PreviewDragDrop" />
</scripts>
</asp:ScriptManager>
可以引用的脚本包括PreviewDragDrop.js、 PreviewGlitz和PreviewScript.js。如果想引用第三方或者自己编写的客户端脚本,那么可以这样:
<asp:ScriptManager id="scriptManager1" runat="server">
<scripts>
<scriptreference scriptname="custom" path="3rd.js"/>
</scripts>
</asp:ScriptManager>
通过为scriptname属性指定“custom”的值,然后使用path属性提供相应js文件的路径即可。
15.3.6 ASP.NET AJAX版本的Hello World
上面简要介绍了ASP.NET AJAX框架的概要,现在通过一个最简单的ASP.NET AJAX的示例,让读者初步了解如何使用ASP.NET AJAX框架。按照下面的步骤来逐步完成这个示例:
(1)新建一个“ASP.NET AJAX”站点,取名为“AtlasDemo”。
(2)在解决方案浏览器中,右键单击站点的名称,选择“添加新项”。
(3) 在“添加新项”对话框中,选择Web 服务,为Web 服务页面命名为HelloWorld.asmx。
(4)点击“添加”,然后HelloWorld.asmx就被添加到了站点解决方案中。
(5)编辑HelloWorld.asmx的代码如下:
using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class HelloWorld : System.Web.Services.WebService {
public HelloWorld () {
}
[WebMethod]
public string HelloWorld(string user) {
return "Hello "+user;
}
}
(6)新建一个ASPX页面,命名为AtlasHello.aspx。
(7)使AtlasHello.aspx页面的HTML代码如下所示。
<%@ Page Language="C#" Title="Atlas Say Hello" AutoEventWireup="true" CodeFile="Default2.aspx.cs"
Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Atlas Say Hello</title>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/HelloWorld.asmx" />
</Services>
</asp:ScriptManager>
</head>
<body>
<form id="form1" runat="server">
<div>
请输入您的姓名:<input id="username" type="text" />
<input id="confirmBtn" type="button" value="button" οnclick="DoSend();" />
</div>
<div id="result"></div>
</form>
<script type="text/javascript" language="javascript">
function DoSend()
{
var user=$get("username").value;
AtlasDemo.HelloWorld.SayHello(user,OnRequestCompleted);
}
function OnRequestCompleted(result)
{
var divelement=$get("result");
divelement.innerHTML=result;
}
</script>
</body>
</html>
编译整个站点,然后运行AtlasHello.aspx页面,在输入框中输入姓名,就可以在页面上发现由HelloWorld.asmx返回的字符串。
上面这个例子示例如何在ASP.NET AJAX应用程序中调用一个Web Service。有几个关键的地方需要注意:
(1) 在<asp:ScriptManager></asp:ScriptManager>标签内部对要使用的Web Service进行了引用:
<Services>
<asp:ServiceReference Path="~/HelloWorld.asmx" />
</Services>
(2) 按照Web Service中,所有调用方法的“命名空间”.“类名”.“方法名”的方式进行调用。例如,在上面例子中DoSend()这个JavaScript方法中的AtlasDemo.HelloWorld.SayHello (user,OnRequestCompleted);
(3)在调用Web Service的方法时,除了要传送必要的参数以外,还应该提供一个回调方法,如上例中的OnRequestCompleted。回调方法将在远程调用完成时调用。另外,还可以传递另外两个回调方法,它们分别会在调用超时和调用出错时调用。
(4)OnRequestCompleted方法中,使用result参数来接收Web Service的返回值,然后将值填入页面中指定的标签内。
以上就是一个最简单的ASP.NET AJAX应用程序。相比15.2节手工编写的JavaScript来实现的AJAX程序简便了不只一个数量级。
15.3.7 UpdatePanel和局部重绘
在上一节曾经提到,可以在启用局部重绘模式的情况下,通过<asp:UpdatePanel .../>标签定义需要异步更新的范围。传统的HTTP应用场景中,客户端在用户点击submit提交form的时候,一个GET/POST请求被发送到后台服务器;服务器则根据form的action指定页面,调用相应的处理者返回HTML格式的文本;返回结果并最终由客户端在浏览器中绘制,通常导致浏览器一次明显的刷新。
这种模式从 Web 早期的CGI一直沿用到现在的 ASP.NET 中。其优点是简单易用且较为成熟,缺点则是刷新明显且速度慢。因为一个页面中可能绝大多数内容在每一次的请求中是无需改变的,而这部分重复的内容在每次请求都会被反复传输,响应速度和负载都是难以容忍的。期间也有过很多缓解方法,例如使用iframe等嵌入帧封装独立部件,或者在服务器端针对不同区域进行缓存等,但因为都还是基于这个传统思路,无法从本质上解决问题。
现在遵循AJAX思想的ASP.NET AJAX框架,则可以真正实现按需重绘。在页面定义时,通过<asp:UpdatePanel/>标签将页面分为几个不同的逻辑区域。然后,ASP.NET AJAX框架将接管ASP.NET使用的PostBack表单。接着,ASP.NET AJAX框架还接管了服务器端的页面重绘方法。最后,重绘的结果通过XML的格式异步发回给客户端,客户端的ASP.NET AJAX脚本引擎决定如何重绘。
下面就来介绍一下UpdatePanel。
UpdatePanel是ASP.NET AJAX框架中非常重要的容器控件。通过它可以把传统的ASP.NET程序与最新的AJAX程序有机地连接在一起。如果已经有了一些基于ASP.NET的网站,通过UpdatePanel仅仅作小小的修改就可以让现有的站点支持AJAX技术。如果开发人员不熟悉JavaScript或者DOM技术,UpdatePanel简直就是救星,它可以让开发人员不写一行客户端代码就能实现非常漂亮的AJAX程序。
使用UpdatePanel非常简单。首先,设定页面的<asp:ScriptManager>组件的属性EnablePartialUpdates=true。UpdatePanel就像一个容器,将要动态更新的控件放到这个容器中。例如:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Time:"></asp:Label>
<asp:TextBox ID="TimeTextBox" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Get Server Time" />
</ContentTemplate>
</asp:UpdatePanel>
如上所示,将要更新的内容放置在UpdatePanel的ContentTemplate中。然后,需要在UpdatePanel中为更新指定触发条件。有两种触发条件,一种是ControlValueTrigger:当某个控件的指定的属性的值发生变化时,UpdatePanel进行更新。例如:
<asp:ControlValueTrigger ControlID="TimeTextBox" PropertyName="Text" />
另一种是ControlEventTrigger。当某个控件某个指定事件发生时,UpdatePanel将进行更新。例如:
<asp:ControlEventTrigger ControlID="Button1" EventName="Click" />
下面即是一个完整的使用UpdatePanel的例子。在AtlasDemo站点中,添加UpdatePanelDemo.aspx页面,页面的HTML代码如下所示:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="updatePanelDemo.aspx.cs"
Inherits="updatePanelDemo"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Time:"></asp:Label>
<asp:TextBox ID="TimeTextBox" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Get Server Time" />
</ContentTemplate>
<Triggers>
<asp:ControlEventTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
上面的代码保存在附赠光盘的“第15章/AtlasDemo/UpdatePanelDemo.aspx”中。
另外,在UpdatePanelDemo.aspx.cs代码中,添加:
protected void Page_Load(object sender, EventArgs e)
{
TimeTextBox.Text = DateTime.Now.ToLongTimeString();
}
这样,一个完整的使用UpdatePanel的例子就完成了。在本章的最后一节,来看一个稍微复杂一点的使用UpdatePanel完成AJAX程序的示例。
15.3.8 AJAX风格的留言板
本节前面的内容对ASP.NET AJAX的内容进行了一个概要的介绍,这一节通过演示如何使用ASP.NET AJAX编写一个AJAX风格的留言板对ASP.NET AJAX做进一步的讲解。
首先来准备留言板的数据库。在这个示例中,留言板的数据库非常简单,仅仅包含一个表,因为并没有考虑用户注册和登录的问题。打开SQL 2005 Management Studio,连接到SQL Server,然后在“DataBase”节点上选择“New DataBase…”。新建数据库MessageBoardDB,如图15-14所示。
图15-14 新建数据库
然后,为MessageBoardDB数据,新增一个表Message。Message的定义如下:
CREATE TABLE [dbo].[message](
[id] [int] IDENTITY(1,1) NOT NULL,
[poster] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL CONSTRAINT [DF_message_poster]
DEFAULT ('Guest'),
[title] [nvarchar](256) COLLATE Chinese_PRC_CI_AS NOT NULL,
[body] [nvarchar](1024) COLLATE Chinese_PRC_CI_AS NOT NULL,
[posttime] [datetime] NOT NULL,
CONSTRAINT [PK_message] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
然后考虑到为留言板提供新增留言和删除留言的功能,因此,创建两个存储过程AddMessage和DeleteMessage。AddMessage代码如下:
-- =============================================
-- Author: Yi Wang
-- Create date: 10-13-2006
-- Description: 新增留言
-- =============================================
CREATE PROCEDURE [dbo].[AddMessage]
-- Add the parameters for the stored procedure here
@poster nvarchar(50),
@title nvarchar(256),
@body nvarchar(1024),
@posttime DateTime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF @poster<>'' AND @title<>'' AND @body<>'' AND @posttime<>''
BEGIN
INSERT INTO message(poster,title,body,posttime) values(@poster,@title, @body,@posttime);
END
END
DeleteMessage代码如下所示:
-- =============================================
-- Author: Yi Wang
-- Create date: 10-13-2006
-- Description: 删除留言
-- =============================================
ALTER PROCEDURE [dbo].[DeleteMessage]
-- Add the parameters for the stored procedure here
@id int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DELETE FROM MESSAGE WHERE id=@id
END
之后就可以用上面这两个存储过程来为数据库添加和删除记录。
现在,在Visual Studio 2005中创建ASP.NET AJAX的Web站点,命名为“AtlasMessageBoard”。在解决方案浏览器中,右击站点名称,选择“添加新项”,添加ASPX页面messages.aspx。在messages.aspx页面中,添加一个ScriptManager,如下所示:
<head runat="server">
<title>Welcome to ASP.NET AJAX Message Board</title>
<asp:ScriptManager ID="ScriptManager1" EnablePartialRendering="true" runat="server" />
</head>
现在添加一个UpdatePanel,并且在UpdatePanel中加入一个SqlDataSource控件和Repeater控件,用来显示留言;另外,添加发送留言所需要的输入控件。代码如下:
<div style="background-color:White">
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString=
"<%$ ConnectionStrings:MessageBoardDbConnectionString %>"
SelectCommand="SELECT * FROM [message] ORDER BY posttime" >
</asp:SqlDataSource>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<table style="background-color: #99ff66;width:400px;">
<tr><td align="right" style="background-color: #6699ff;width:100px;border:solid 1px
black"><b>Post User:</b></td><td style="width:300px"><%# Eval("Poster")%></td></tr>
<tr><td align="right" style="background-color: #ff99ff;width:100px;border:solid 1px
black"><b>Title:</b></td><td style="width:300px"><%# Eval("Title")%></td></tr>
<tr><td align="right" style="background-color: #ccff66;width:100px;border:solid 1px
black"><b>Message</b></td><td style="width:300px"><textarea style="width:300px;height:200px; border-right:
#ff6666 thin solid; border-top: #ff6666 thin solid; border-left: #ff6666 thin solid; border-bottom: #ff6666 thin solid;"
readonly="readonly" rows="8"><%# Eval("body")%></textarea></td></tr>
<tr><td align="right" style="background-color: #ffd0c4;width:100px;border:solid 1px
black"><b>Time:</b></td><td style="width:300px"><%# Eval("posttime")%>
<asp:LinkButton ID="LinkButton1" runat="server" OnCommand="OnDelete"
CommandName="Delete" CommandArgument='<%# Eval("id")%>>删除</asp:LinkButton></td></tr>
<tr></tr>
</table>
<br />
</ItemTemplate>
</asp:Repeater>
<br />
<asp:Label ID="Label1" runat="server" BackColor="#99FF66" Text="添加新的留言:" Width="400px"></asp:Label><br />
<asp:Label ID="Label2" runat="server" Text="昵称:" Width="68px"></asp:Label>
<asp:TextBox ID="NicknameTextBox" runat="server" Width="91px"></asp:TextBox><br />
<asp:Label ID="Label3" runat="server" Text="标题:" Width="67px"></asp:Label>
<asp:TextBox ID="TitleTextBox" runat="server" Width="327px"></asp:TextBox><br />
<asp:Label ID="Label4" runat="server" Text="内容:" Width="66px"></asp:Label><br />
<asp:TextBox ID="MessageTextBox" runat="server" Height="185px" Width="398px" TextMode="MultiLine"></asp:TextBox>
<br />
<asp:Button ID="SendBtn" runat="server" Text="添加留言" OnClick="SendBtn_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
上面的代码保存在附赠光盘的“第15章/AtlasMessageBoard/Messages.aspx”中。
如上所示,在UpdatePanel的ContentTemplate标签内,定义了要显示的内容和要更新的内容。
响应的Messages.aspx.cs代码如下所示:
public partial class Messages : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
Repeater1.DataBind();
}
protected void SendBtn_Click(object sender, EventArgs e)
{
if ((MessageTextBox.Text.Length > 0) && (TitleTextBox.Text.Length > 0) &&
(NicknameTextBox.Text.Length > 0))
{
SqlConnection connection = new
SqlConnection(ConfigurationManager.ConnectionStrings["MessageBoardDbConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand("AddMessage");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("@poster", NicknameTextBox.Text);
cmd.Parameters.AddWithValue("@title", TitleTextBox.Text);
cmd.Parameters.AddWithValue("@body", MessageTextBox.Text);
cmd.Parameters.AddWithValue("posttime", DateTime.Now);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
System.Threading.Thread.Sleep(1000);
Repeater1.DataBind();
}
}
protected void OnDelete(object sender, CommandEventArgs e)
{
using (SqlConnection connection = new
SqlConnection(ConfigurationManager.ConnectionStrings["MessageBoardDbConnectionString"].ConnectionString))
{
SqlCommand cmd = new SqlCommand("DeleteMessage");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("@id", e.CommandArgument);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
System.Threading.Thread.Sleep(1000);
Repeater1.DataBind();
}
}
}
上面的代码保存在附赠光盘的“第15章/AtlasMessageBoard/Messages.aspx.cs”中。现在就可以运行这个站点进行测试了。Messages.aspx页面运行效果如图15-15和图15-16所示。
现在填入必要的信息,点击“添加留言”,页面在没有刷新的情况下,新的留言信息被加入了进来,如图15-16所示。
图15-15 第一次运行Messages.aspx页面的效果 图15-16 添加留言之后
随着留言的不断增加,留言表单上面的留言记录也随着增加。现在讲解一下上面的程序是怎么样工作的。当页面加载时,SqlDataSource控件从MessageBoardDB数据库获取现存的留言记录,然后Repeater控件绑定到SqlDataSource控件,从而显示留言记录。在使用页面下方的输入框输入留言信息以后,点击“添加留言”,留言就通过服务器端代码添加到了数据库。此时,重新绑定Repeater以获取更新之后的数据库信息。由于Repeater处在UpdatePanel内部,所以当Repeater的内容发生变化时,UpdatePanel仅重绘了Repeater,而不用重新刷新整个页面。
当使用这个留言程序时,发现由于数据库服务器和Web服务器都在同一台机器上,页面的响应非常迅速。那么服务器响应有比较明显的延迟的时候,还应该做些什么呢?为了让用户感觉到其操作的有效性,有必要在操作完成之前,在页面上给予一定的提示。在Messages.aspx中,在UpdatePanel后,添加下面的组件:
<asp:UpdateProgress ID="Progress1" runat="server">
<ProgressTemplate>
<div style="background-color: #99ff99; font-size: 16pt; color: #cc33ff; font-family: YouYuan, STXihei, STZhongsong, SimHei, LiSu; left: 800px; width: 200px; position: absolute; top: 20px; height: 50px;">
请稍后...提交中
</div>
</ProgressTemplate>
</asp:UpdateProgress>
当用户在UpdatePanel中的操作在服务器完全响应之前,UpdateProgress组件中ProgressTemplate的内容将会显示出来。为了能清楚地看见UpdateProgress的显示效果,在Messages.aspx.cs代码的方法中,增加了System.Threading.Thread.Sleep(1000)方法的调用。此时,添加留言和删除浏览就都会有如图15-17所示的效果。
图15-17 UpdateProgress的效果
还可以在ProgressTemplate中添加动态的GIF图片,让信息更加生动。
这就是整个ASP.NET AJAX的留言板示例。通过这个例子,可以发现,通过UpdatePanel,开发ASP.NET AJAX应用程序和开发一般的ASP.NET程序并没有多大区别,不需要做什么改动就可以让程序支持ASP.NET AJAX。
由于ASP.NET AJAX包含的内容相当丰富,完全可以写成一本厚厚的书,因此本节的介绍只能算浅尝辄止。ASP.NET AJAX包含了许多AJAX风格的控件、可以扩展的控件行为、数据绑定、以及如何使用服务器端的成员管理服务等功能,本节由于篇幅限制不能将ASP.NET AJAX的全貌展现出来。希望对ASP.NET AJAX有兴趣的读者能继续阅读相关资料和书籍,深入下去。ASP.NET AJAX非常值得学习。