您的位置:首页 > 编程语言 > ASP

探索AJAX中的消息传输模式(一)

2008-06-23 20:05 441 查看
在我们使用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">
用户通过点击HyperLink控件,客户端向服务器发送请求,返回的数据可能来自不同的地方(数据库,XML,普通的文件.....),这里以Message类来封装这些数据,详细代码定义如下:




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

}
方法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.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

}
在客户端的处理程序上,大致和上面的普通的文本消息差不多,其实整个AJAX应用基本上都是应用的一个模式,从发送请求--->响应请求--->数据传输--->处理回调。客户端工作量最大的就是在回调函数里,下面是本示例的回调函数定义:
1

//回调函数

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

html.append("<td bgcolor='lightblue'><b>City</b></td>");

117

if(cbCountry.checked)

118

html.append("<td bgcolor='lightblue'><b>Country</b></td>");

119

html.append("<tr>");

120


121

//构建数据行

122

for (var i=0; i<employees.length;i++)

123





{

124

html.append("<tr>");

125

if(cbID.checked)

126





{

127

var id= employees[i].getElementsByTagName("EmployeeID")[0].childNodes[0].nodeValue;

128

html.append("<td>"+id+"</td>");

129

}

130

if(cbLastName.checked)

131





{

132

var LastName= employees[i].getElementsByTagName("LastName")[0].childNodes[0].nodeValue;

133

html.append("<td>"+LastName+"</td>");

134

}

135

if(cbCity.checked)

136





{

137

var City= employees[i].getElementsByTagName("City")[0].childNodes[0].nodeValue;

138

html.append("<td>"+City+"</td>");

139

}

140

if(cbCountry.checked)

141





{

142

var Country= employees[i].getElementsByTagName("Country")[0].childNodes[0].nodeValue;

143

html.append("<td>"+Country+"</td>");

144

}

145

html.append("</tr>");

146

}

147


148

html.append("</table>");

149

resultXml.innerHTML=html.toString();

150

}

151

</script>

152

</form>

153

</body>

154

</html>

155




文章中有部分内容我作了修改,在原文中加入了示例分析。希这篇文章对大家有所帮助,要更深入的学习AJAX是数据传输请查阅其他相关书籍或资料。欢迎大家拍砖指正,谢谢。

-------------------------------------------------------------------------------------------------------------

参考资源:www.dofactory.com

相关文章:探索AJAX中的消息传输模式(二)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  职场 ajax asp.net 休闲