当前位置:中文知识网 → 站长学院 → 网页设计 → WEB标准 → 探索AJAX中的消息传输模式(一)
探索AJAX中的消息传输模式(一)
在我们使用AJAX的应用中,消息传输有那些方式呢?纯文本、带HTML的文本、XML、JSON?还有???在许多情况下,纯文本的消息传输就足够了。例如,要传输一个用户名,用户密码,或是用户联系方法(PHONE,EMAIL,MSN)等,通常都是以文本的形式传输的。又比如复杂点的数据信息,表格、对象或者是???,这样我们可以使用XML或是JSON来格式化数据后进行传输。
有这样一个AJAX的应用场合,提供一系列的标签连接,让用户任意选择,浏览器向服务器发送请求查询得到想要的数据信息。下面就以这个应用讨论下消息传输。
一、普通的文本消息传输
建立一ASP.NET AJAX应用程序,先为AJAXMessageText.aspx页面做好简单的布局准备,我们采用HyperLink控件做为导航连接,放置在一个table里,并设置一单元格作为数据显示区,设置其作为服务器控件运行(runat="server"),如下图示:

各个控件的命名以数据显示区的名称如下:
1
<asp:HyperLink ID="hlAjax" runat="server" Text="AJAX" NavigateUrl="JavaScript:void(0);" />
2
<asp:HyperLink ID="hlAspnet" runat="server" Text="ASP.NET" NavigateUrl="JavaScript:void(0);" />
3
<asp:HyperLink ID="hlCastle" runat="server" Text="Castle" NavigateUrl="JavaScript:void(0);" />
4
<asp:HyperLink ID="hlService" runat="server" Text="WebService" NavigateUrl="JavaScript:void(0);" />
5
<asp:HyperLink ID="hlHtml" runat="server" Text="Html" NavigateUrl="JavaScript:void(0);"/>
6
<td runat="server" colspan="2" rowspan="5" style="background-color: #00ffff; text-align: left" valign="top" id="resultText">
Message
1
/**//// <summary>
2
/// Message 的摘要说明
3
/// </summary>
4
public class Message
5

{
6
public string AJAX=string.Empty;
7
public string ASPNET=string.Empty;
8
public string CASTLE=string.Empty;
9
public string WEBSERVICE=string.Empty;
10
public string HTML = string.Empty;
11
12
StringBuilder str = null;
13
14
public Message()
15
{
16
str = new StringBuilder();
17
str.Append("Ajax提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。");
18
str.Append("借助于Ajax,可以在用户单击按钮时,使用JavaScript和DHTML立即更新UI,");
19
str.Append(" 并向服务器发出异步请求,以执行更新或查询数据库。");
20
AJAX = str.ToString();
21
22
23
str = new StringBuilder();
24
str.Append("Microsoft 的 ASP.NET 和 Visual Studio 组将出席于曼德勒海湾度假举行的 ASP.NET Connections 会议。");
25
str.Append("请参加深入而前沿的 ASP.NET、Visual Studio & .NET、SQL 和 Mobile Connections 交流会并同与会的");
26
str.Append("Microsoft 和业界专家会晤。即时了解 Microsoft 许多令人惊喜的公告。");
27
ASPNET = str.ToString();
28
29
str = new StringBuilder();
30
str.Append("Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架、AOP,");
31
str.Append("基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务。");
32
CASTLE = str.ToString();
33
34
35
str = new StringBuilder();
36
str.Append("Web Service 是在 Internet 上进行分布式计算的基本构造块,是组件对象技术在 Internet 中的延伸,");
37
str.Append("是一种部署在 Web 上的组件。它融合了以组件为基础的开发模式和 Web 的出色性能。");
38
WEBSERVICE = str.ToString();
39
40
str = new StringBuilder();
41
str.Append("<span style="+"font-weight:bold;font-size:20;color:Red;>");
42
str.Append("带有HTML的字符串,返回此字符串,所拥有的样式等都可以得到解析!");
43
str.Append("</span>");
44
HTML = str.ToString();
45
}
46
}
在ASP.NET AJAX应用中,客户端和服务器端进行数据通信绝大多数都是通过WebService来完成,这里我们为Message所类的数据方便了与客户端交互提供一个WebService:
1
[WebService(Namespace = "http://tempuri.org/")]
2
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
3
[ScriptService]
4
public class MessageWebService : System.Web.Services.WebService
{
5
6
public MessageWebService ()
{ }
7
8
[WebMethod]
9
public string GetMessage(string text)
10
{
11
Message message = new Message();
12
string str = string.Empty;
13
switch (text)
14
{
15
case "AJAX": str = message.AJAX; break;
16
case "ASPNET": str = message.ASPNET; break;
17
case "CASTLE": str = message.CASTLE; break;
18
case "SERVER": str = message.WEBSERVICE; break;
19
case "HTML": str = message.HTML; break;
20
}
21
return str;
22
}
23
}
<asp:ScriptManager ID="ScriptManager1" runat="server">
2
<Services>
3
<asp:ServiceReference Path="MessageWebService.asmx" />
4
</Services>
5
</asp:ScriptManager>
在客户端,通过ASP.NET AJAX对JavaScript的扩展,我们可以很方便的得到各个控件的引用,以及调用WebService方法,设置回调函数来处理返回值,下面是客户端JS的完整代码:
1
<script type="text/javascript">
2
var hlAjax;
3
var hlAspnet;
4
var hlCastle;
5
var hlService;
6
var hlHtml;
7
var resultText;
8
9
//初始化控件引用及事件
10
function pageLoad()
11
{
12
hlAjax = $get("<% =hlAjax.ClientID %>");
13
hlAspnet = $get("<% =hlAspnet.ClientID %>");
14
hlCastle = $get("<% =hlCastle.ClientID %>");
15
hlService = $get("<% =hlService.ClientID %>")
16
hlHtml = $get("<% = hlHtml.ClientID %>");
17
18
$addHandler(hlAjax,"click",onClick);
19
$addHandler(hlAspnet,"click",onClick);
20
$addHandler(hlCastle,"click",onClick);
21
$addHandler(hlService,"click",onClick);
22
$addHandler(hlHtml,"click",onClick);
23
24
resultText = $get("<% = resultText.ClientID %>");
25
}
26
27
function onClick(eventElement)
28
{
29
var topic = false;
30
switch(eventElement.target.id)
31
{
32
case hlAjax.id:topic = "AJAX";break;
33
case hlAspnet.id:topic = "ASPNET";break;
34
case hlCastle.id:topic = "CASTLE";break;
35
case hlService.id:topic = "SERVER";break;
36
case hlHtml.id:topic = "HTML";break;
37
38
}
39
//引用WebService获取数据
40
MessageWebService.GetMessage(topic,onGetTextMessageCallback);
41
}
42
43
//回调函数
44
function onGetTextMessageCallback(text)
45
{
46
resultText.innerHTML=text;
47
}
48
</script>
上述中,通过AJAX所提供的$get()方法获取到各控件的客户端引用,并通过$addHandler()方法为其添加了客户端事件,注意有个HTML的连接,这里我们追逐到Message类里:
1
str = new StringBuilder();
2
str.Append("<span style="+"font-weight:bold;font-size:20;color:Red;>");
3
str.Append("带有HTML的字符串,返回此字符串,所拥有的样式等都可以得到解析!");
4
str.Append("</span>");
5
HTML = str.ToString(); 类里所封装的html对应的字符传是带有css样式及html标识的字符串,返回这个html字符串那客户端是否能得到解析??答案是肯定的,这里只是做到了用户点击相应的连接就发送请求到服务器,要使这个应用完善,我们还得为这个应用初始化一个显示值:
1
public partial class AjaxMessageText : System.Web.UI.Page
2

{
3
protected void Page_Load(object sender, EventArgs e)
4
{
5
this.resultText.InnerHtml = new Message().AJAX;
6
}
7
}
看看下面的运行结果:

二、复杂类型的消息传输
我们模拟一个数据库查询功能,根据客户端的请求条件查询数据库,把查询到的数据返回到客户端显示。这样一个应用一般来说可以通过XML来传输。ASPX页面设计如下:

正如上图所示,以MSSQL2000里的Northwind数据库里的Employees表为例,根据客户端的条件(排序字段,提取的记录条数)查询数据库,下面是数据库访问代码:

数据库访问代码
1
public class DataAccess
2

{
3
private static string strCon = "Data Source=.;database=northwind;uid=sa;pwd=;";
4
public DataAccess()
5
{
6
}
7
8
public static DataTable GetEmployees(string orderBy, int maxRows)
9
{
10
string cmdText = "select top " + maxRows;
11
cmdText += " EmployeeID,LastName,City,Country ";
12
cmdText += "from Employees order by " + orderBy;
13
return Exce(cmdText);
14
}
15
16
private static DataTable Exce(string cmdText)
17
{
18
SqlConnection conn = new SqlConnection(strCon);
19
SqlDataAdapter sda = new SqlDataAdapter(cmdText, conn);
20
DataSet ds = new DataSet();
21
sda.Fill(ds);
22
return ds.Tables[0];
23
}
24
}
数据库访问方法GetEmployees提供根据客户传递的参数查询Employees表里的数据并以DataTable的形式返回,到这里我们同上面一样可以借助WebService来处理返回的DataTable,将数据处理为一个XML字符串返回到客户端:
1
[WebMethod]
2
public string GetEmployees(string orderBy, int manxRows)
3

{
4
DataTable dt = DataAccess.GetEmployees(orderBy, manxRows);
5
StringBuilder xml = new StringBuilder();
6
xml.Append("<?xml version='1.0' ?>");
7
xml.Append("<Employees>");
8
9
foreach (DataRow row in dt.Rows)
10
{
11
string id = row["EmployeeID"].ToString();
12
string name = row["LastName"].ToString();
13
string city = row["City"].ToString();
14
string country = row["Country"].ToString();
15
xml.Append("<Employee>");
16
xml.Append("<EmployeeID>" + id + "</EmployeeID>");
17
xml.Append("<LastName>" + name + "</LastName>");
18
xml.Append("<City>" + city + "</City>");
19
xml.Append("<Country>" + country + "</Country>");
20
xml.Append("</Employee>");
21
}
22
xml.Append("</Employees>");
23
return xml.ToString();
24
}
//回调函数
2
function onXmlMessageCallback(result)
3

{
4
var xml;
5
if(window.ActiveXObject) //IE
6
{
7
xml = new ActiveXObject("Microsoft.XMLDOM");
8
xml.async = false;
9
xml.loadXML(result);
10
}
11
else
12
{
13
var parser = new DOMParser();
14
xml = parser.parseFromString(result,"text/xml");
15
}
16
17
var employees = xml.getElementsByTagName("Employee");
18
var html = new Sys.StringBuilder();
19
html.append("<table width='500px' cellspacing='1' cellpadding='0' border='0' bgcolor='#999999'>");
20
//构建表头
21
html.append("<tr>");
22
if(cbID.checked)
23
html.append("<td bgcolor='lightblue'><b>ID</b></td>");
24
if(cbLastName.checked)
25
html.append("<td bgcolor='lightblue'><b>LastName</b></td>");
26
if(cbCity.checked)
27
html.append("<td bgcolor='lightblue'><b>City</b></td>");
28
if(cbCountry.checked)
29
html.append("<td bgcolor='lightblue'><b>Country</b></td>");
30
html.append("<tr>");
31
32
//构建数据行
33
for (var i=0; i<employees.length;i++)
34
{
35
html.append("<tr>");
36
if(cbID.checked)
37
{
38
var id= employees[i].getElementsByTagName("EmployeeID")[0].childNodes[0].nodeValue;
39
html.append("<td>"+id+"</td>");
40
}
41
if(cbLastName.checked)
42
{
43
var LastName= employees[i].getElementsByTagName("LastName")[0].childNodes[0].nodeValue;
44
html.append("<td>"+LastName+"</td>");
45
}
46
if(cbCity.checked)
47
{
48
var City= employees[i].getElementsByTagName("City")[0].childNodes[0].nodeValue;
49
html.append("<td>"+City+"</td>");
50
}
51
if(cbCountry.checked)
52
{
53
var Country= employees[i].getElementsByTagName("Country")[0].childNodes[0].nodeValue;
54
html.append("<td>"+Country+"</td>");
55
}
56
html.append("</tr>");
57
}
58
59
html.append("</table>");
60
resultXml.innerHTML=html.toString();
61
}
在客户端的回调函数里,把服务器端返回的字符串解析为一个xml对象,通过JavaScript操作DOM将xml对象里的每一条数据解析后存入数组,随后根据页面上选择要显示字段动态构造html代码并显示在指定的位置(resutlXml)。 下面是客户端的完整代码:
客户端的完整代码
1
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxMessageXML.aspx.cs" Inherits="AjaxMessageXML" %>
2
3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5
<html xmlns="http://www.w3.org/1999/xhtml" >
6
<head runat="server">
7
<title>无标题页</title>
8
</head>
9
<body>
10
<form id="form1" runat="server">
11
<asp:ScriptManager ID="ScriptManager1" runat="server">
12
<Services>
13
<asp:ServiceReference Path="MessageWebService.asmx" />
14
</Services>
15
</asp:ScriptManager>
16
以MSSQL 2000里的示例数据库Northwind里的Employees表为例<br />
17
所要显示的列
18
19
方式字段 提取记录行数<br />
20
<asp:CheckBox ID="cbID" runat="server" Text="ID" />
21
22
<asp:CheckBox ID="cbLastName" runat="server" Text="LastName" />
23
24
<asp:CheckBox ID="cbCity" runat="server" Text="City" />
25
26
<asp:CheckBox ID="cbCountry" runat="server" Text="Country" />
27
28
<asp:DropDownList ID="ddlOrder" runat="server">
29
<asp:ListItem Value="EmployeeID" Text="ID"></asp:ListItem>
30
<asp:ListItem Value="LastName" Text="LastName"></asp:ListItem>
31
<asp:ListItem Value="City" Text="City"></asp:ListItem>
32
<asp:ListItem Value="Country" Text="Country"></asp:ListItem>
33
</asp:DropDownList>
34
<asp:DropDownList ID="ddlRows" runat="server">
35
<asp:ListItem>1</asp:ListItem>
36
<asp:ListItem>2</asp:ListItem>
37
<asp:ListItem>3</asp:ListItem>
38
<asp:ListItem>5</asp:ListItem>
39
<asp:ListItem>8</asp:ListItem>
40
<asp:ListItem>10</asp:ListItem>
41
</asp:DropDownList>
42
43
<input id="buttonGO" style="width: 53px" type="button" value="GO" />
44
<hr />
45
<div id="resultXml"></div>
46
47
<script type="text/javascript">
48
var cbID;
49
var cbLastName;
50
var cbCity;
51
var cbCountry;
52
var ddlOrder;
53
var ddlRows;
54
var resultXml;
55
var buttonGO;
56
57
//初始化控件引用及事件
58
function pageLoad()
59
{
60
cbID = $get("<% =cbID.ClientID %>");
61
cbLastName = $get("<% =cbLastName.ClientID %>");
62
cbCity = $get("<% =cbCity.ClientID %>");
63
cbCountry = $get("<% =cbCountry.ClientID %>");
64
65
ddlOrder = $get("<% =ddlOrder.ClientID %>");
66
ddlRows = $get("<% =ddlRows.ClientID %>");
67
68
resultXml = $get("resultXml");
69
buttonGO = $get("buttonGO");
70
$addHandler(buttonGO,"click",onButtonClicked);
71
72
onButtonClicked(null);
73
}
74
75
function onButtonClicked(eventElement)
76
{
77
if(!cbID.checked && !cbLastName.checked && cbCity.checked && cbCountry.checked)
78
{
79
alert("至少选择一列!");
80
return;
81
}
82
83
var orderBy = ddlOrder.options[ddlOrder.selectedIndex].value;
84
var maxRows = ddlRows.options[ddlRows.selectedIndex].value;
85
86
//调用WebService获取数据
87
MessageWebService.GetEmployees(orderBy,maxRows,onXmlMessageCallback);
88
}
89
90
//回调函数
91
function onXmlMessageCallback(result)
92
{
93
var xml;
94
if(window.ActiveXObject) //IE
95
{
96
xml = new ActiveXObject("Microsoft.XMLDOM");
97
xml.async = false;
98
xml.loadXML(result);
99
}
100
else
101
{
102
var parser = new DOMParser();
103
xml = parser.parseFromString(result,"text/xml");
104
}
105
106
var employees = xml.getElementsByTagName("Employee");
107
var html = new Sys.StringBuilder();
108
html.append("<table width='500px' cellspacing='1' cellpadding='0' border='0' bgcolor='#999999'>");
109
//构建表头
110
html.append("<tr>");
111
if(cbID.checked)
112
html.append("<td bgcolor='lightblue'><b>ID</b></td>");
113
if(cbLastName.checked)
114
html.append("<td bgcolor='lightblue'><b>LastName</b></td>");
115
if(cbCity.checked)
116
有这样一个AJAX的应用场合,提供一系列的标签连接,让用户任意选择,浏览器向服务器发送请求查询得到想要的数据信息。下面就以这个应用讨论下消息传输。
一、普通的文本消息传输
建立一ASP.NET AJAX应用程序,先为AJAXMessageText.aspx页面做好简单的布局准备,我们采用HyperLink控件做为导航连接,放置在一个table里,并设置一单元格作为数据显示区,设置其作为服务器控件运行(runat="server"),如下图示:

各个控件的命名以数据显示区的名称如下:
1
<asp:HyperLink ID="hlAjax" runat="server" Text="AJAX" NavigateUrl="JavaScript:void(0);" />2
<asp:HyperLink ID="hlAspnet" runat="server" Text="ASP.NET" NavigateUrl="JavaScript:void(0);" />3
<asp:HyperLink ID="hlCastle" runat="server" Text="Castle" NavigateUrl="JavaScript:void(0);" />4
<asp:HyperLink ID="hlService" runat="server" Text="WebService" NavigateUrl="JavaScript:void(0);" />5
<asp:HyperLink ID="hlHtml" runat="server" Text="Html" NavigateUrl="JavaScript:void(0);"/>6
<td runat="server" colspan="2" rowspan="5" style="background-color: #00ffff; text-align: left" valign="top" id="resultText">用户通过点击HyperLink控件,客户端向服务器发送请求,返回的数据可能来自不同的地方(数据库,XML,普通的文件.....),这里以Message类来封装这些数据,详细代码定义如下:
1

/**//// <summary>2
/// Message 的摘要说明3
/// </summary>4
public class Message5


{6
public string AJAX=string.Empty;7
public string ASPNET=string.Empty;8
public string CASTLE=string.Empty;9
public string WEBSERVICE=string.Empty;10
public string HTML = string.Empty; 11

12
StringBuilder str = null;13

14
public Message()15

{16
str = new StringBuilder();17
str.Append("Ajax提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。");18
str.Append("借助于Ajax,可以在用户单击按钮时,使用JavaScript和DHTML立即更新UI,");19
str.Append(" 并向服务器发出异步请求,以执行更新或查询数据库。");20
AJAX = str.ToString();21

22

23
str = new StringBuilder();24
str.Append("Microsoft 的 ASP.NET 和 Visual Studio 组将出席于曼德勒海湾度假举行的 ASP.NET Connections 会议。");25
str.Append("请参加深入而前沿的 ASP.NET、Visual Studio & .NET、SQL 和 Mobile Connections 交流会并同与会的");26
str.Append("Microsoft 和业界专家会晤。即时了解 Microsoft 许多令人惊喜的公告。");27
ASPNET = str.ToString();28

29
str = new StringBuilder();30
str.Append("Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架、AOP,");31
str.Append("基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务。");32
CASTLE = str.ToString();33

34

35
str = new StringBuilder();36
str.Append("Web Service 是在 Internet 上进行分布式计算的基本构造块,是组件对象技术在 Internet 中的延伸,");37
str.Append("是一种部署在 Web 上的组件。它融合了以组件为基础的开发模式和 Web 的出色性能。");38
WEBSERVICE = str.ToString();39

40
str = new StringBuilder();41
str.Append("<span style="+"font-weight:bold;font-size:20;color:Red;>");42
str.Append("带有HTML的字符串,返回此字符串,所拥有的样式等都可以得到解析!");43
str.Append("</span>");44
HTML = str.ToString();45
}46
}在ASP.NET AJAX应用中,客户端和服务器端进行数据通信绝大多数都是通过WebService来完成,这里我们为Message所类的数据方便了与客户端交互提供一个WebService:
1
[WebService(Namespace = "http://tempuri.org/")]2
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]3
[ScriptService]4

public class MessageWebService : System.Web.Services.WebService
{5

6

public MessageWebService ()
{ }7

8
[WebMethod]9
public string GetMessage(string text)10

{11
Message message = new Message();12
string str = string.Empty;13
switch (text)14

{15
case "AJAX": str = message.AJAX; break;16
case "ASPNET": str = message.ASPNET; break;17
case "CASTLE": str = message.CASTLE; break;18
case "SERVER": str = message.WEBSERVICE; break;19
case "HTML": str = message.HTML; break;20
}21
return str;22
}23
}方法GetMessage提供根据客户端传递过来的参数返回Message类里所封装的相应数据。此时,我们就应该着手客户端请求的发送处理,在ASP.NET AJAX应用里,我们可以很方便的通过ScriptManager引入WebService:
1
<asp:ScriptManager ID="ScriptManager1" runat="server">2
<Services>3
<asp:ServiceReference Path="MessageWebService.asmx" />4
</Services>5
</asp:ScriptManager> 在客户端,通过ASP.NET AJAX对JavaScript的扩展,我们可以很方便的得到各个控件的引用,以及调用WebService方法,设置回调函数来处理返回值,下面是客户端JS的完整代码:
1
<script type="text/javascript">2
var hlAjax;3
var hlAspnet;4
var hlCastle;5
var hlService;6
var hlHtml;7
var resultText;8
9
//初始化控件引用及事件10
function pageLoad()11

{12
hlAjax = $get("<% =hlAjax.ClientID %>");13
hlAspnet = $get("<% =hlAspnet.ClientID %>");14
hlCastle = $get("<% =hlCastle.ClientID %>");15
hlService = $get("<% =hlService.ClientID %>")16
hlHtml = $get("<% = hlHtml.ClientID %>");17
18
$addHandler(hlAjax,"click",onClick);19
$addHandler(hlAspnet,"click",onClick);20
$addHandler(hlCastle,"click",onClick);21
$addHandler(hlService,"click",onClick);22
$addHandler(hlHtml,"click",onClick);23
24
resultText = $get("<% = resultText.ClientID %>");25
}26
27
function onClick(eventElement)28

{29
var topic = false;30
switch(eventElement.target.id)31

{32
case hlAjax.id:topic = "AJAX";break;33
case hlAspnet.id:topic = "ASPNET";break;34
case hlCastle.id:topic = "CASTLE";break;35
case hlService.id:topic = "SERVER";break;36
case hlHtml.id:topic = "HTML";break;37
38
}39
//引用WebService获取数据40
MessageWebService.GetMessage(topic,onGetTextMessageCallback);41
}42
43
//回调函数44
function onGetTextMessageCallback(text)45

{46
resultText.innerHTML=text;47
}48
</script>上述中,通过AJAX所提供的$get()方法获取到各控件的客户端引用,并通过$addHandler()方法为其添加了客户端事件,注意有个HTML的连接,这里我们追逐到Message类里:
1
str = new StringBuilder();2
str.Append("<span style="+"font-weight:bold;font-size:20;color:Red;>");3
str.Append("带有HTML的字符串,返回此字符串,所拥有的样式等都可以得到解析!");4
str.Append("</span>");5
HTML = str.ToString(); 类里所封装的html对应的字符传是带有css样式及html标识的字符串,返回这个html字符串那客户端是否能得到解析??答案是肯定的,这里只是做到了用户点击相应的连接就发送请求到服务器,要使这个应用完善,我们还得为这个应用初始化一个显示值:1
public partial class AjaxMessageText : System.Web.UI.Page2


{3
protected void Page_Load(object sender, EventArgs e)4

{5
this.resultText.InnerHtml = new Message().AJAX;6
}7
}看看下面的运行结果:

二、复杂类型的消息传输
我们模拟一个数据库查询功能,根据客户端的请求条件查询数据库,把查询到的数据返回到客户端显示。这样一个应用一般来说可以通过XML来传输。ASPX页面设计如下:

正如上图所示,以MSSQL2000里的Northwind数据库里的Employees表为例,根据客户端的条件(排序字段,提取的记录条数)查询数据库,下面是数据库访问代码:
1
public class DataAccess2


{3
private static string strCon = "Data Source=.;database=northwind;uid=sa;pwd=;";4
public DataAccess()5

{6
}7

8
public static DataTable GetEmployees(string orderBy, int maxRows)9

{10
string cmdText = "select top " + maxRows;11
cmdText += " EmployeeID,LastName,City,Country ";12
cmdText += "from Employees order by " + orderBy;13
return Exce(cmdText);14
}15

16
private static DataTable Exce(string cmdText)17

{18
SqlConnection conn = new SqlConnection(strCon);19
SqlDataAdapter sda = new SqlDataAdapter(cmdText, conn);20
DataSet ds = new DataSet();21
sda.Fill(ds);22
return ds.Tables[0];23
}24
}数据库访问方法GetEmployees提供根据客户传递的参数查询Employees表里的数据并以DataTable的形式返回,到这里我们同上面一样可以借助WebService来处理返回的DataTable,将数据处理为一个XML字符串返回到客户端:
1
[WebMethod]2
public string GetEmployees(string orderBy, int manxRows)3


{4
DataTable dt = DataAccess.GetEmployees(orderBy, manxRows);5
StringBuilder xml = new StringBuilder();6
xml.Append("<?xml version='1.0' ?>");7
xml.Append("<Employees>");8

9
foreach (DataRow row in dt.Rows)10

{11
string id = row["EmployeeID"].ToString();12
string name = row["LastName"].ToString();13
string city = row["City"].ToString();14
string country = row["Country"].ToString();15
xml.Append("<Employee>");16
xml.Append("<EmployeeID>" + id + "</EmployeeID>");17
xml.Append("<LastName>" + name + "</LastName>");18
xml.Append("<City>" + city + "</City>");19
xml.Append("<Country>" + country + "</Country>");20
xml.Append("</Employee>");21
}22
xml.Append("</Employees>");23
return xml.ToString();24
}在客户端的处理程序上,大致和上面的普通的文本消息差不多,其实整个AJAX应用基本上都是应用的一个模式,从发送请求--->响应请求--->数据传输--->处理回调。客户端工作量最大的就是在回调函数里,下面是本示例的回调函数定义:
1
//回调函数2
function onXmlMessageCallback(result)3


{4
var xml;5
if(window.ActiveXObject) //IE6

{7
xml = new ActiveXObject("Microsoft.XMLDOM");8
xml.async = false;9
xml.loadXML(result);10
}11
else12

{13
var parser = new DOMParser();14
xml = parser.parseFromString(result,"text/xml");15
}16
17
var employees = xml.getElementsByTagName("Employee");18
var html = new Sys.StringBuilder();19
html.append("<table width='500px' cellspacing='1' cellpadding='0' border='0' bgcolor='#999999'>");20
//构建表头21
html.append("<tr>");22
if(cbID.checked)23
html.append("<td bgcolor='lightblue'><b>ID</b></td>");24
if(cbLastName.checked)25
html.append("<td bgcolor='lightblue'><b>LastName</b></td>"); 26
if(cbCity.checked)27
html.append("<td bgcolor='lightblue'><b>City</b></td>"); 28
if(cbCountry.checked)29
html.append("<td bgcolor='lightblue'><b>Country</b></td>");30
html.append("<tr>");31
32
//构建数据行33
for (var i=0; i<employees.length;i++)34

{35
html.append("<tr>");36
if(cbID.checked)37

{38
var id= employees[i].getElementsByTagName("EmployeeID")[0].childNodes[0].nodeValue;39
html.append("<td>"+id+"</td>");40
}41
if(cbLastName.checked)42

{43
var LastName= employees[i].getElementsByTagName("LastName")[0].childNodes[0].nodeValue;44
html.append("<td>"+LastName+"</td>");45
}46
if(cbCity.checked)47

{48
var City= employees[i].getElementsByTagName("City")[0].childNodes[0].nodeValue;49
html.append("<td>"+City+"</td>");50
}51
if(cbCountry.checked)52

{53
var Country= employees[i].getElementsByTagName("Country")[0].childNodes[0].nodeValue;54
html.append("<td>"+Country+"</td>");55
}56
html.append("</tr>");57
}58
59
html.append("</table>");60
resultXml.innerHTML=html.toString();61
}在客户端的回调函数里,把服务器端返回的字符串解析为一个xml对象,通过JavaScript操作DOM将xml对象里的每一条数据解析后存入数组,随后根据页面上选择要显示字段动态构造html代码并显示在指定的位置(resutlXml)。 下面是客户端的完整代码:
1

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxMessageXML.aspx.cs" Inherits="AjaxMessageXML" %>2

3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">4

5
<html xmlns="http://www.w3.org/1999/xhtml" >6
<head runat="server">7
<title>无标题页</title>8
</head>9
<body>10
<form id="form1" runat="server">11
<asp:ScriptManager ID="ScriptManager1" runat="server">12
<Services>13
<asp:ServiceReference Path="MessageWebService.asmx" />14
</Services>15
</asp:ScriptManager>16
以MSSQL 2000里的示例数据库Northwind里的Employees表为例<br />17
所要显示的列 18
19
方式字段 提取记录行数<br />20
<asp:CheckBox ID="cbID" runat="server" Text="ID" />21
22
<asp:CheckBox ID="cbLastName" runat="server" Text="LastName" />23
24
<asp:CheckBox ID="cbCity" runat="server" Text="City" />25
26
<asp:CheckBox ID="cbCountry" runat="server" Text="Country" />27
28
<asp:DropDownList ID="ddlOrder" runat="server">29
<asp:ListItem Value="EmployeeID" Text="ID"></asp:ListItem>30
<asp:ListItem Value="LastName" Text="LastName"></asp:ListItem>31
<asp:ListItem Value="City" Text="City"></asp:ListItem>32
<asp:ListItem Value="Country" Text="Country"></asp:ListItem>33
</asp:DropDownList>34
<asp:DropDownList ID="ddlRows" runat="server">35
<asp:ListItem>1</asp:ListItem>36
<asp:ListItem>2</asp:ListItem>37
<asp:ListItem>3</asp:ListItem>38
<asp:ListItem>5</asp:ListItem>39
<asp:ListItem>8</asp:ListItem>40
<asp:ListItem>10</asp:ListItem>41
</asp:DropDownList>42
43
<input id="buttonGO" style="width: 53px" type="button" value="GO" />44
<hr />45
<div id="resultXml"></div>46
47

<script type="text/javascript">
48
var cbID;49
var cbLastName;50
var cbCity;51
var cbCountry;52
var ddlOrder;53
var ddlRows;54
var resultXml;55
var buttonGO;56
57
//初始化控件引用及事件58
function pageLoad()59

{60
cbID = $get("<% =cbID.ClientID %>");61
cbLastName = $get("<% =cbLastName.ClientID %>");62
cbCity = $get("<% =cbCity.ClientID %>");63
cbCountry = $get("<% =cbCountry.ClientID %>");64
65
ddlOrder = $get("<% =ddlOrder.ClientID %>");66
ddlRows = $get("<% =ddlRows.ClientID %>");67
68
resultXml = $get("resultXml");69
buttonGO = $get("buttonGO");70
$addHandler(buttonGO,"click",onButtonClicked);71
72
onButtonClicked(null);73
}74
75
function onButtonClicked(eventElement)76

{77
if(!cbID.checked && !cbLastName.checked && cbCity.checked && cbCountry.checked)78

{79
alert("至少选择一列!");80
return;81
}82
83
var orderBy = ddlOrder.options[ddlOrder.selectedIndex].value;84
var maxRows = ddlRows.options[ddlRows.selectedIndex].value;85
86
//调用WebService获取数据87
MessageWebService.GetEmployees(orderBy,maxRows,onXmlMessageCallback);88
}89
90
//回调函数91
function onXmlMessageCallback(result)92

{93
var xml;94
if(window.ActiveXObject) //IE95

{96
xml = new ActiveXObject("Microsoft.XMLDOM");97
xml.async = false;98
xml.loadXML(result);99
}100
else101

{102
var parser = new DOMParser();103
xml = parser.parseFromString(result,"text/xml");104
}105
106
var employees = xml.getElementsByTagName("Employee");107
var html = new Sys.StringBuilder();108
html.append("<table width='500px' cellspacing='1' cellpadding='0' border='0' bgcolor='#999999'>");109
//构建表头110
html.append("<tr>");111
if(cbID.checked)112
html.append("<td bgcolor='lightblue'><b>ID</b></td>");113
if(cbLastName.checked)114
html.append("<td bgcolor='lightblue'><b>LastName</b></td>"); 115
if(cbCity.checked)116
