ASP.NET中的AJAX应用开发总结
Posted 周金桥讲堂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET中的AJAX应用开发总结相关的知识,希望对你有一定的参考价值。
AJAX介绍
Ajax 即“Asynchronous javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。其实AJAX应用的核心就是XMLHttpRequest,通过现象看本质,即使使用微软的AJAX服务器控件最终也是需要这些的,只不过使用微软AJAX服务器控件开发AJAX应用时我们不需要关心JS脚本的实现,只需关心业务逻辑就可以了,因而可以简化开发和提高开发速度。AJAX的基础是Xhtml、CSS、DOM、JavaScript、XML及XMLHttpRequest。
正确使用AJAX技术可以改善用户体验,是用户与服务器的交互更流畅,某些情况下还能减少服务器流量。在以前AJAX只是作为一种比较炫的技术为一些大型网站所使用,现今这个比云计算还要流行了,至少云计算更多地还是停留在人们的概念里,而AJAX确确实实应用在WEB开发当中了。WEB开发人员的招聘都是言必精通AJAX技术。
下面分别讲讲在ASP.NET开发中可以供选择的开发AJAX应用的方式:
采用纯JavaScript实现
在武侠小说中绝顶高手飞花摘叶都可以伤人,在WEB开发领域真正的高手也可以无需借助任何其它库就可以开发出AJAX应用。不适用任何第三方库开发AJAX应用就需要自己区分浏览器来实例化XMLHttpRequest对象实例,下面的代码是一个简单的调用AJAX的代码:
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>获取服务器时间的例子</title>
<script language="javascript"type="text/javascript">
var request=false;
//实例化XMLHttpRequest
function createXMLHttpRequest()
{
try
{
//下面的方法有可能抛出异常,表示当前浏览器不支持此方法
request=newActivexObject("Msxml2.XMLHTTP");
}
catch(e1)//当通过上面的方法实例XMLHttpRequest发生异常
{
try
{
//下面的方法有可能抛出异常,表示当前浏览器不支持此方法
request=newActivexObject("Microsoft.XMLHTTP");
}
catch(e2)//当通过上面的方法实例XMLHttpRequest发生异常
{
request=false;
}
}
//当上面的方法都不能实例化XMLHttpRequest时,表示非IE浏览器
if(!request&&typeof XMLHttpRequest!='undefined')
{
//非IE浏览器实例化XMLHttpRequest的方法
request=new XMLHttpRequest();
}
}
//发送客户端请求的方法
function getServerTime(format)
{
//调用上面的方法实例化XMLHttpRequest
createXMLHttpRequest();
//用于对特殊字符进行转义
var url="ServerTime.aspx?format="+escape(format);
//alert(url);//可以通过这种方法查看服务器的返回结果
//通过GET方式打开请求,第三个参数true表示异步发送请求,false则为同步
request.open("GET",url,true);
//当request的等待状态发生变化时要执行的客户端方法
request.onreadystatechange=update;//update是客户端的javascript方法
//因为在请求的url中已经附带了参数,所以这里的参数是null
//表示不再发送额外的数据
request.send(null);
}
//当接收到服务器的响应之后执行的客户端方法
function update()
{
if(request.readyState==4)
{
//alert(request.responseText);//查看服务器响应结果
document.getElementById("time").innerHTML=request.responseText;
}
}
</script>
</head>
<body>
<table border="0">
<tr>
<td>服务器时间</td><td><divid="time"></div></td>
</tr>
<tr>
<td><input type="button" value="完整时间"onclick="javascript:void getServerTime('yyyy-mm-dd hh:mm:ss');" /></td><td><inputtype="button" value="年月日" onclick="javascript:voidgetServerTime('yyyy-MM-dd');" /></td>
</tr>
<tr>
<td><input type="button" value="时分秒"onclick="javascript:void getServerTime('hh:mm:ss');"/></td><td><input type="button" value="月份日期" onclick="javascript:voidgetServerTime('mm-dd');" /></td>
</tr>
</table>
</body>
</html>
注意XMLHttpRequest.readyState共有5种状态,其可能值和对应描述如下:
0:请求未初始化,还没有调用 open()。
1:请求已经建立,但是还没有发送,还没有调用 send()。
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
3:请求在处理中;通常响应中已有部分数据可用了,没有全部完成。
4:响应已完成;您可以获取并使用服务器的响应了。
从上面的代码中可以看出每次实例化XMLHttpRequest对象都需要判断,一些常用的操作也可以封装一下,利用Prototype这个JavaScript脚本库就可以轻松做到这一点,实际上早期很多人就用到了Prototype来开发AJAX应用,并且在Prototype中还封装了其它很多通用的方法,大大提高了我们的开发效率。
使用Prototype
在Prototype中提供了一个Ajax对象,这样开发人员就可以直接使用Ajax对象而不必考虑如何判断浏览器类型再决定如何实例化XMLHttpRequest对象的实例了。下面的代码是使用了Protype之后的代码:
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用Prototype获取服务器时间的例子</title>
<script type="text/javascript"language="javascript" ></script>
<script language="javascript"type="text/javascript">
function getServerTime(format) {
//用于对特殊字符进行转义
var url ="ServerTime.aspx";
var params = "format=" +escape(format);
var ajax = new Ajax.Request(
url,
{
method: 'get',
parameters:params,
onComplete:update
}
);
}
//当接收到服务器的响应之后执行的客户端方法
function update(request) {
$("time").innerHTML =request.responseText;
}
</script>
</head>
<body>
<table border="0">
<tr>
<td>服务器时间</td><td><divid="time"></div></td>
</tr>
<tr>
<td><input type="button" value="完整时间"onclick="javascript:void getServerTime('yyyy-mm-dd hh:mm:ss');" /></td><td><inputtype="button" value="年月日" onclick="javascript:voidgetServerTime('yyyy-MM-dd');" /></td>
</tr>
<tr>
<td><input type="button" value="时分秒"onclick="javascript:void getServerTime('hh:mm:ss');"/></td><td><input type="button" value="月份日期" onclick="javascript:void getServerTime('mm-dd');"/></td>
</tr>
</table>
</body>
</html>
从上面的代码可以看出使用了一些相对较为成熟的JavaScript框架之后可以使我们的代码大大减少,开发速度也得到了提高。当然我们还可以使用目前比较热门的JavaScript框架jQuery,这个在VS2008中需要安装SP1后才能活得智能提示,在VS2010中已经集成了。如果使用jQuery上面的代码可以简化为:
<!DOCTYPEhtml PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用jQuery获取服务器时间的例子</title>
<scriptsrc="jquery-1.2.6-cn.js"type="text/javascript"></script>
<script type="text/javascript"language="javascript">
function getTime() {
$.get("GetTime.aspx", {format: "yyyy-mm-dd hh:mm:ss" },
function(data) {//得到Ajax响应后的回调函数
//$("#time").append("<font color='red'>" +data + "</font>");
$("#time").html("<font color='red'>" + data +"</font>");
});
}
</script>
</head>
<body>
<tableborder="0">
<tr>
<td>服务器时间</td><td><divid="time"></div></td>
</tr>
<tr>
<td><input type="button" value="完整时间"onclick="javascript:void getServerTime('yyyy-mm-dd hh:mm:ss');" /></td><td><inputtype="button" value="年月日" onclick="javascript:voidgetServerTime('yyyy-MM-dd');" /></td>
</tr>
<tr>
<td><input type="button"value="时分秒"onclick="javascript:void getServerTime('hh:mm:ss');"/></td><td><input type="button" value="月份日期" onclick="javascript:voidgetServerTime('mm-dd');" /></td>
</tr>
</table>
</body>
</html>
可以看出在jQuery中提供了更多、更灵活的处理AJAX和XHTML的方法,简易大家都去了解一下。
在上面的方式中无论使用自己写全部JavaScript脚本还是利用Protype或者jQuery这类框架的方式,都是需要写一些JS脚本的,有没有尽可能少写脚本的方式呢?毕竟我们知道JS脚本调试起来相对较为困难些。答案是有的,那就是使用AjaxPro。
使用AjaxPro
下面是一个使用AjaxPro的例子,设计代码如下:
<%@ Page Language="C#"AutoEventWireup="true" CodeFile="AjaxPager.aspx.cs" Inherits="AjaxPager"%>
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>AjaxPro翻页效果</title>
<style type="text/css">
tr.items{
background-color:#8FACC2;
border-color:#FFFFFF;
line-height:18px;
}
tr.table{ /*表格内容*/
background-color:#F1F3F5;
border-color:#FFFFFF;
line-height:18px;
}
</style>
</head>
<bodyonload="JumpPage(0)">
<form id="form1" runat="server">
<div id="memberList">
数据装载中,请等待.....
</div>
</form>
<script language="javascript"type="text/javascript" defer="defer">
function JumpPage(var page)
{
var label=document.getElementById("memberList");
label.innerHTML=AjaxPager.GetString(parseInt(page*20),parseInt(20)).value;//假定每页显示20条数据
}
</script>
</body>
</html>
后台逻辑代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
public partial class AjaxPager :System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Cache["Data"] == null)
{
InitData();
}
AjaxPro.Utility.RegisterTypeForAjax(typeof(AjaxPager));
}
/// <summary>
/// 从数据库中指定位置读取指定数目的数据
/// </summary>
/// <param name="startIndex">记录的起始位置</param>
/// <param name="size">要读取的记录条数</param>
/// <returns></returns>
[AjaxPro.AjaxMethod]
public DataTable GetDataTable(int startIndex, int size)
{
DataTable source = (DataTable)Cache["Data"];
DataTable tempData = new DataTable();
int j = 0;
for (int i = startIndex; i <source.Rows.Count && j < size; i++, j++)
{
tempData.Rows.Add(source.Rows[i]);
}
return tempData;
}
/// <summary>
/// 传递div节点的html字符串
/// </summary>
/// <param name="startIndex"></param>
/// <param name="size"></param>
/// <returns></returns>
[AjaxPro.AjaxMethod]
public string GetString(int startIndex, int size)
{
StringBuilder text = newStringBuilder();
text.Append("<table border='0'cellpadding='0' cellspacing='0' width='520px'>");
text.Append("<tralign='center'>");
text.Append("<tdstyle='width:80px'>编号</td>");
text.Append("<tdstyle='width:80px'>姓名</td>");
text.Append("<tdstyle='width:80px'>年龄</td>");
text.Append("<tdstyle='width:80px'>性别</td>");
text.Append("<tdstyle='width:80px'>身高</td>");
text.Append("<td style='width:80px'>工资</td>");
text.Append("</tr>");
DataTable source =(DataTable)Cache["Data"];
int j = 0;
DataRow row;
for (int i = startIndex; i <source.Rows.Count && j < size; i++, j++)
{
row = source.Rows[i];
for (int column = 0; column <source.Columns.Count; column++)
{
text.Append("<trclass='items'>");
text.Append("<tdstyle='width:80px'>"+row[column].ToString()+"</td>");
text.Append("</tr>");
}
//tempData.Rows.Add(source.Rows[i]);
}
return text.ToString();
}
/// <summary>
/// 返回记录总条数
/// </summary>
/// <returns></returns>
[AjaxPro.AjaxMethod]
public int GetRecordCount()
{
DataTable source =(DataTable)Cache["Data"];
return source.Rows.Count;
}
/// <summary>
/// 说明:此处实际情况应该从数据库读取数据,因为本程序主要是演示如何分页的,所以我在这里用程序生成数据
/// </summary>
public void InitData()
{
string firstName = "赵钱孙李周吴郑王冯程诸卫金卫陶姜";
string lastName = "青雁蓉玲猛勇刚强雪萍";
Random random = new Random();
DataTable data = new DataTable();
data.Columns.Add(new DataColumn("编号", typeof(int)));
data.Columns.Add(new DataColumn("姓名", typeof(string)));
data.Columns.Add(new DataColumn("年龄", typeof(int)));
data.Columns.Add(new DataColumn("性别", typeof(string)));
data.Columns.Add(new DataColumn("身高", typeof(int)));
data.Columns.Add(new DataColumn("工资", typeof(int)));
DataRow row;
for (int i = 1; i < 100; i++)
{
row = data.NewRow();
row["编号"] = i;
row["姓名"] =firstName[random.Next(DateTime.Now.Millisecond) % firstName.Length] + lastName[random.Next(DateTime.Now.Millisecond)% lastName.Length];
row["年龄"] = 10 +random.Next(DateTime.Now.Millisecond) % 30;
row["性别"] =random.Next(DateTime.Now.Millisecond) % 2 == 0 ? "男" : "女";
row["身高"] = 150 + random.Next(DateTime.Now.Millisecond)% 50;
row["工资"] = 1000 +random.Next(DateTime.Now.Millisecond) * 10;
data.Rows.Add(row);
}
Cache["Data"] = data;
}
}
从上面的代码中可以看出使用AjaxPro之后可以不用写太多客户端代码,而且不同前面几种做法需要写一个页面调用显示,一个页面负责控制业务逻辑(一般情况下是这样的),使用AjaxPro可以将调用页面和控制业务逻辑页面合在一起,这样服务端代码调试比较方面,而且也不用控制如何发送请求,请求什么时候响应完毕。
使用AjaxPro有几方面需要注意,就上面的代码中的注意事项说明如下:
使用微软AJAX控件库
前面几种开发AJAX应用的方式都是遵循一个规律:开发速度是有低到高,开发难易程度由难到易,不过在前面几种方式中不管怎么做都还没有完全脱离JavaScript,这个东东对于现在的一些初学者(就是那些感觉做ASP.NET开发就只是拖拽控件)来说还是有些难度,还是需要写JavaScript来操作HTML页面,为了彻底减轻这部分人掌握ASP.NET中AJAX开发,微软推出了AJAX服务器端控件。
使用微软AJAX服务器端控件可以在做简单设置的情况下满足开发环境中的大部分简单需求,当然做一些稍微复杂点的设置就可以满足开发环境中的绝大部分需求了。
在微软AJAX服务器控件库中主要有以下几个服务器控件:
ScriptManager控件:注册脚本,必须在所有服务器控件之前出现
ScriptManagerProxy控件:参考其它脚本和服务
UpdatePanel控件:局部刷新控件
Timer控件:定时执行控件
UpdateProgress控件:进度显示控件
下面是一个使用了微软AJAX服务器控件的例子:
<%@ Page Language="C#"AutoEventWireup="true" CodeFile="Register.aspx.cs"Inherits="Register" %>
<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>用户注册</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManagerID="ScriptManager1" runat="server">
</asp:ScriptManager>
<table border="0">
<tr><td>用户名</td><td>
<asp:UpdatePanelID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:TextBoxrunat="server" ID="txtUserName"AutoPostBack="True"
ontextchanged="txtUserName_TextChanged"></asp:TextBox>
<asp:LabelID="lbStatus" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="txtUserName"EventName="TextChanged" />
</Triggers>
</asp:UpdatePanel>
</td></tr>
<tr><td>密码</td><td><asp:TextBox runat="server"ID="txtPwd"TextMode="Password"></asp:TextBox></td></tr>
<tr><td>确认密码</td><td><asp:TextBox runat="server"ID="txtConfirmPwd"TextMode="Password"></asp:TextBox></td></tr>
<tr><td>找回密码提示问题</td><td><asp:TextBox runat="server"ID="txtPwdQuestion"></asp:TextBox></td></tr>
<tr><td>找回密码提示答案</td><td><asp:TextBox runat="server"ID="txtPwdAnswer"></asp:TextBox></td></tr>
<tr><td>籍贯</td><td>
<asp:UpdatePanelID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownListID="ddlProvince" runat="server"AppendDataBoundItems="True"
AutoPostBack="True"DataTextField="ProvinceName" DataValueField="ProvinceID"
onselectedindexchanged="ddlProvince_SelectedIndexChanged">
<asp:ListItemValue="0">请选择</asp:ListItem>
</asp:DropDownList>
省<asp:DropDownList ID="ddlCity" runat="server"AutoPostBack="True"
DataTextField="CityName" DataValueField="CityID"
onselectedindexchanged="ddlCity_SelectedIndexChanged">
</asp:DropDownList>
市<asp:DropDownList ID="ddlRegionalism"runat="server" AutoPostBack="True"
DataTextField="RegionalismName"DataValueField="RegionalismID">
</asp:DropDownList>
县(区)
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlProvince"
EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTriggerControlID="ddlCity"
EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="ddlRegionalism"
EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
</td></tr>
<tr><td> </td><td>
<asp:ButtonID="btnRegister" runat="server" Text="注册"
onclick="btnRegister_Click" />
<input id="Reset1"type="reset" value="reset" /></td></tr>
</table>
</form>
</body>
</html>
这个页面的作用其实很简单,就是在用户打开这个注册页面填写完自己的用户名之后准备填写其它信息(就是鼠标从用户名文本框移开后)时就能获知自己的用户名是否已经被注册,还有另外一个效果,就是在用户注册时实现了省(直辖市)、市(区县)、县三级联动的效果,因为使用了微软AJAX控件,所以操作过程中整个页面不会全部刷新,只有局部刷新效果。
在使用微软AJAX服务器控件过程中需要注意一些事项,就上面的例子中需要注意的事项如下:
总结:
其实这篇文章是新瓶装旧酒(和AJAX一样),里面用到的代码都是以前在博客文章中出现的,这篇文章只不过做了一个综合性的比较而已。
对于上面出现的这么多选择,我们不必一味去追问哪种比哪种一定要好,实际上很多技术都有自己的使用场合的,没有绝对在所有领域所有场合都是最佳的(那就好像找一匹不吃草且跑得快的马)。控制越灵活的需要对脚本知识掌握越高,开发速度也相对低;开发速度越高、调试越容易的控制起来相对较难一些(就像武学一样,绝对高手飞花摘叶可以杀人,花花草草找起来很简单,但是没有深厚的功力不行;倚天屠龙即使在普通人手里也可以让他威力大增,但是不是每个人都有这种机会)。
其实这里面讲到的一些技术比如Protype、AjaxPro、AjaxUpdatePanel是在早年曾经被一些人用过(2006-2010),在那时候的一些项目里可能会看到他们的影子,现在基本上都是用jQuery或者原生Javsscript(有人嫌jQuery越来越庞大了),所以我们主要是明白Ajax的实现原理,反正我面试Web开发相关的知识时,基本上都会问这方面的知识。
以上是关于ASP.NET中的AJAX应用开发总结的主要内容,如果未能解决你的问题,请参考以下文章