ASP.NET AJAX应用程序
2.2 ASP.NET AJAX应用程序
下一步是使用这个新框架建立一个基本示例。首先使用New Web Site对话框创建一个新的ASP.NET Web Site应用程序,把项目命名为AjaxWebSite。如图2-3所示,注意,没有一个单独的ASP.NET项目类型用于建立ASP.NET AJAX应用程序,因为现在建立的每个ASP.NET应用程序都支持AJAX。
图 2-3
创建了应用程序后,屏幕就会显示一个标准的Web site项目。但在ASP.NET 3.5新建的web.config文件中有一些额外的设置。在web.config文件的顶部,有一些注册的新配置段,用于处理AJAX。这段web.config代码如程序清单2-1所示。
程序清单2-1 ASP.NET 3.5应用程序的<configSections>元素
<configuration>
<configSections>
<sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting"
type="System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler"
type="System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices"
type="System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization"
type="System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="Everywhere" />
<section name="profileService"
type="System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="authenticationService"
type="System.Web.Configuration.
ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="roleService"
type="System.Web.Configuration.ScriptingRoleServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<! -- Configuration removed for clarity -- >
</configuration>
<configSections> 元素现在是web.config的一部分,除此之外,还有一个新的<system.webServer>片段。这一段用于在IIS 7.0的环境中运行的ASP.NET AJAX应用程序。这段配置代码如程序清单2-2所示。
程序清单2-2 用于AJAX和IIS 7.0的<system.webServer>段
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<remove name="ScriptModule" />
<add name="ScriptModule" preCondition="managedHandler"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<remove name="ScriptHandlerFactory" />
<remove name="ScriptHandlerFactoryAppServices" />
<remove name="ScriptResource" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx"
preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*"
path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD"
path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" />
</handlers></system.webServer>
web.config文件有了这些段(ASP.NET Web Site项目类型会提供)后,下一步就是建立一个还没有使用AJAX的ASP.NET简单页面。
2.2.1 建立未使用AJAX的ASP.NET简单页面
首先是建立一个ASP.NET简单页面,它还没有使用ASP.NET 3.5提供的AJAX功能。页面只有一个标签控件和一个按钮服务器控件。页面的代码如程序清单2-3所示。
程序清单2-3 未使用AJAX的ASP.NET 3.5简单页面
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>My Normal ASP.NET Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"></asp:Label>
<br >
<br >
<asp:Button ID="Button1" runat="server" Text="Click to get machine time"
onclick="Button1_Click" />
</div>
</form>
</body>
</html>
在浏览器中打开这个页面时,该页面只包含一个按钮。单击该按钮,页面上的标签控件就会填充服务器的时间。在单击按钮前,页面的代码如程序清单2-4所示。
程序清单2-4 未使用AJAX的页面的页面输出
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
My Normal ASP.NET Page
</title></head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwULLTE4OTg4OTc0MjVkZIgwrMMmvqXJHfogxzgZ92wTUORS" />
</div>
<div>
<span id="Label1"></span>
<br >
<br >
<input type="submit" name="Button1" value="Click to get machine time"
id="Button1" />
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="/wEWAgLFpoapCAKM54rGBkhUDe2q/7eVsROfd9QCMK6CwiI7" />
</div></form>
</body>
</html>
这段代码没有什么新东西。ViewState很小,还有一个回送给Default.aspx页面的典型窗体。终端用户单击页面上的按钮时,就会给服务器回送整个页面,服务器重新处理整个页面,然后返回给客户机的浏览器。对页面的唯一修改是给<span id="Lable1"></span>元素填充了一个值。但在这个例子中,返回了整个页面,返回的内容如程序清单2-5所示。
程序清单2-5 从按钮单击事件返回的代码
<head id="Head1"><title>
My Normal ASP.NET Page
</title></head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKLTE2MjY5MTY1NQ9kFgICAw9kFgICAQ8PFgIeBFRleHQFEzcvMy8yMDA
4IDU6MzM6NDAgQU1kZGSDYMwC9k0QFgaZvlblIaJEWMQxIA==" />
</div>
<div>
<span id="Label1">7/3/2008 5:33:40 AM</span>
<br >
<br >
<input type="submit" name="Button1" value="Click to get machine time"
id="Button1" />
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="/wEWAgLFsJKtCwKM54rGBmLn3/qARdTOYYDTaj6+5D8E4bEQ" />
</div></form>
</body>
</html>
从这段代码可以看出,把整个页面都返回给了客户机。这个过程使整个页面在浏览器上消失,然后重载(产生闪烁)。所有这些工作和线上移动的数据都只处理页面上一小部分变化的内容。
接着再建立一个简单的ASP.NET页面,它使用内置的ASP.NET AJAX功能。
2.2.2 建立使用AJAX的ASP.NET页面
前面的第一个例子是不以任何方式使用AJAX的简单页面,下面要以程序清单2-3中的页面为基础,添加内置的AJAX功能。对于这个例子,要添加一些控件。我们添加的是一般的ASP.NET服务器控件:一个标签控件和一个按钮服务器控件。除了这些控件之外,还要添加一些ASP.NET AJAX控件。
在Visual Studio 2008工具箱上有一个新选项卡AJAX Extensions。这个新选项卡包含ASP.NET 3.5提供的新AJAX控件,该选项卡如图2-4所示。
图 2-4
从Visual Studio 2008工具箱的AJAX Extensions组中,把一个ScriptManager服务器控件放在ASP.NET页面的顶部,在UpdatePanel控件中包含第二个标签和第二个按钮控件。UpdatePanel控件是一个模板服务器控件,在其中可以包含任意多项(与其他ASP.NET模板服务器控件相同)。建立好页面后,设计视图应如图2-5所示。
完成了ASP.NET页面的设计视图后,这个页面的代码应如程序清单2-6所示。
程序清单2-6 简单的ASP.NET AJAX页面
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
protected void Button2_Click(object sender, EventArgs e)
{
Label2.Text = DateTime.Now.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>My ASP.NET AJAX Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Label ID="Label1" runat="server"></asp:Label>
<br >
<br >
<asp:Button ID="Button1" runat="server" Text="Click to get machine time"
onclick="Button1_Click" />
<br >
<br >
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label2" runat="server" Text=""></asp:Label>
<br >
<br >
<asp:Button ID="Button2" runat="server"
Text="Click to get machine time using AJAX"
onclick="Button2_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
图 2-5
在浏览器中打开这个页面,该页面有两个按钮。第一个按钮会回送整个页面,更新Label1服务器控件中的当前时间。
单击第二个按钮会进行AJAX异步回送。单击这个按钮会更新Label2服务器控件中的当前时间。单击AJAX按钮时,Label1中的时间不会变化,因为它在UpdatePanel的外部。最终结果如图2-6所示。
图 2-6
读者可能以为,页面最初布局所需的代码与没有使用AJAX的页面非常类似(但不相同),但第一次在浏览器中打开程序清单2-6中的页面时,会发现该页面的代码与前面建立的没有AJAX的页面大不相同。程序清单2-7显示了页面的结果。
程序清单2-7 使用AJAX的页面的输出
<head><title>
My ASP.NET AJAX Page
</title></head>
<body>
<form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwULLTE4NzE5NTc5MzRkZDRIzHpPZg4GaO9Hox9A/RnOflkm" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms[‘form1’];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<script src="/AJAXWebSite/WebResource.axd?d=o84znEjn4cYi0Wg0pFXCg2&
amp;t=633285028458684000" type="text/javascript"></script>
<script src="/AJAXWebSite/ScriptResource.axd?
d=FETsh5584DXpx8XqIhEM50YSKyR2GkoMoAqraYEDU5_
gi1SUmL2Gt7rQTRBAw56lSojJRQe0OjVI8SiYDjmpYmFP0
CO8wBFGhtKKJwm2MeE1&t=633285035850304000" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
if (typeof(Sys) === ‘undefined’) throw new Error(‘ASP.NET AJAX client-side
framework failed to load.’);
//]]>
</script>
<script src="/AJAXWebSite/ScriptResource.axd?
d=FETsh5584DXpx8XqIhEM50YSKyR2GkoMoAqraYEDU5_
gi1SUmL2Gt7rQTRBAw56l7AYfmRViCoO2lZ3XwZ33TGiC
t92e_UOqfrP30mdEYnJYs09ulU1xBLj8TjXOLR1k0&t=633285035850304000"
type="text/javascript"></script>
<div>
<script type="text/javascript">
//<![CDATA[
Sys.WebForms.PageRequestManager._initialize(‘ScriptManager1’,
document.getElementById(‘form1’));
Sys.WebForms.PageRequestManager.getInstance()._updateControls([‘tUpdatePanel1’],
[], [], 90);
//]]>
</script>
<span id="Label1"></span>
<br >
<br >
<input type="submit" name="Button1" value="Click to get machine time"
id="Button1" />
<br >
<br >
<div id="UpdatePanel1">
<span id="Label2"></span>
<br >
<br >
<input type="submit" name="Button2" value="Click to get machine
time using AJAX" id="Button2" />
</div>
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="/wEWAwLktbDGDgKM54rGBgK7q7GGCMYnNq57VIqmVD2sRDQqfnOsgWQK" />
</div>
<script type="text/javascript">
//<![CDATA[
Sys.Application.initialize();
//]]>
</script>
</form>
</body>
</html>
在这个页面结果中,如果单击Button1,执行整个页面的回送操作,就会在响应中得到上述全部代码——即使只更新页面的一小部分,也是如此。其原因是根本没有使用AJAX功能。但是,如果单击 Button2(该按钮专门用于处理页面的底层AJAX功能),就会把程序清单2-8中的请求发送给后端服务器。
程序清单2-8 来自ASP.NET AJAX页面的异步请求
POST /AJAXWebSite/Default.aspx HTTP/1.1
Accept: */*
Accept-Language: en-US
Referer: http://localhost.:62203/AJAXWebSite/Default.aspx
x-microsoftAJAX: Delta=true
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Cache-Control: no-cache
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1;
.NET CLR 2.0.50727;
Media Center PC 5.0; .NET CLR 1.1.4322; .NET CLR 3.5.21022; .NET CLR
3.0.04506)
Host: localhost.:62203
Content-Length: 334
Proxy-Connection: Keep-Alive
Pragma: no-cache
ScriptManager1=UpdatePanel1%7CButton2&__EVENTTARGET=&__EVENTARGUMENT=
&__VIEWSTATE=%2FwEPDwULLTE4NzE5NTc5MzQPZBYCAgQPZBYCAgMPDxYCHgRUZXh0BRQx
MS8zLzIwMDcgMjoxNzo1NSBQTWRkZHZxUyYQG0M25t8U7vLbHRJuKlcS&__EVENTVALIDAT
ION=%2FwEWAwKCxdk9AoznisYGArursYYI1844hk7V466AsW31G5yIZ73%2Bc6o%3D&Butt
on2=Click%20to%20get%20machine%20time%20using%20Ajax
为这个请求返回的响应如程序清单2-9所示。
程序清单2-9 来自ASP.NET AJAX页面的异步响应
HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Thu, 03 Jul 2008 10:44:25 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Length: 796
Connection: Close
239|updatePanel|UpdatePanel1|
<span id="Label2">07/3/2008 5:44:25 AM</span>
<br />
<br />
<input type="submit" name="Button2" value="Click to get
machine time using AJAX" id="Button2" />
|172|hiddenField|__VIEWSTATE|/wEPDwULLTE4NzE5NTc5MzQPZBYCAgQPZBYEAgMPDx
YCHgRUZXh0BRQxMS8zLzIwMDcgMjoxNzo1NSBQTWRkAgcPZBYCZg9kFgICAQ8PFgIfAAUUM
TEvMy8yMDA3IDI6MTc6NTggUE1kZGQ4ipZIg91+XSI/dqxFueSUwcrXGw==|56|hiddenFi
eld|__EVENTVALIDATION|/wEWAwKCz4mbCAK7q7GGCAKM54rGBj8b4/mkKNKhV59qX9SdC
zqU3AiM|0|asyncPostBackControlIDs|||0|postBackControlIDs|||13|updatePan
elIDs||tUpdatePanel1|0|childUpdatePanelIDs|||12|panelsToRefreshIDs||Upd
atePanel1|2|asyncPostBackTimeout||90|12|formAction||Default.aspx|22|pag
e Title||My ASP.NET AJAX Page|
技巧:
要以程序清单2-9的方式查看请求和响应,可以使用任意HTTP嗅探器,这里推荐使用www.fiddlertool.com上的Fiddler。
从程序清单2-9可以看出,响应比整个Web页面小得多。还要注意,这个输出还包含HTTP标题,实际上,响应的主要部分只是包含UpdatePanel在服务器控件中的代码。底部的项处理页面的ViewState(因为它变化了)和其他一些小的页面变化。
如果不使用AJAX,在进行回送时,整个页面会重载到浏览器中。此时,浏览器有明显的闪烁,因为需要删除以前的显示,再显示新的内容。用户一般会注意到这个中断,在处理应用程序时,这会打断人们的思路。
这与用户使用桌面应用程序时习惯的流畅响应完全不同,可能会引起用户的不满。这种“单击—暂停—闪动”模式是UpdatePanel控件可以解决的问题。Web应用程序现在几乎可以与胖客户端 Windows应用程序一样快速响应。在客户机和服务器之间传送数据仍会导致很短的延迟,但现在容易忍受多了。在许多情况下,用户几乎察觉不到这些延迟,因为我们可以分布式处理更新,以避免所有的更新同时发生。
对执行修改页面的响应较小时,页面的性能就比较好。如果只更新页面中需要修改的局部,而不把重复的代码传输到线上,让处理引擎解释这些代码,再传输回来,页面的性能就好得多(页面越大,性能越好)。
最重要的优点是终端用户使用应用程序的UI时,会觉得流畅许多。应用程序对终端用户的响应快了许多。
http://book.csdn.net/bookfiles/1239/100123936876.shtml
加支付宝好友偷能量挖...