在我们使用AJAX的应用中,消息传输有那些方式呢?纯文本、带HTML的文本、XML、JSON?还有???在许多情况下,纯文本的消息传输就足够了。例如,要传输一个用户名,用户密码,或是用户联系方法(PHONE,EMAIL,MSN)等,通常都是以文本的形式传输的。又比如复杂点的数据信息,表格、对象或者是???,这样我们可以使用XML或是JSON来格式化数据后进行传输。
有这样一个AJAX的应用场合,提供一系列的标签连接,让用户任意选择,浏览器向服务器发送请求查询得到想要的数据信息。下面就以这个应用讨论下消息传输。
一、普通的文本消息传输
建立一ASP.NET AJAX应用程序,先为AJAXMessageText.aspx页面做好简单的布局准备,我们采用HyperLink控件做为导航连接,放置在一个table里,并设置一单元格作为数据显示区,设置其作为服务器控件运行(runat="server"),如下图示:
各个控件的命名以数据显示区的名称如下:
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" >
在ASP.NET AJAX应用中,客户端和服务器端进行数据通信绝大多数都是通过WebService来完成,这里我们为Message所类的数据方便了与客户端交互提供一个WebService:
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}
2 < Services >
3 < asp:ServiceReference Path = " MessageWebService.asmx " />
4 </ Services >
5 </ asp:ScriptManager >
在客户端,通过ASP.NET AJAX对JavaScript的扩展,我们可以很方便的得到各个控件的引用,以及调用WebService方法,设置回调函数来处理返回值,下面是客户端JS的完整代码:
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类里:
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字符串那客户端是否能得到解析??答案是肯定的,这里只是做到了用户点击相应的连接就发送请求到服务器,要使这个应用完善,我们还得为这个应用初始化一个显示值:
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表为例,根据客户端的条件(排序字段,提取的记录条数)查询数据库,下面是数据库访问代码:
数据库访问方法GetEmployees提供根据客户传递的参数查询Employees表里的数据并以DataTable的形式返回,到这里我们同上面一样可以借助WebService来处理返回的DataTable,将数据处理为一个XML字符串返回到客户端:
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)。 下面是客户端的完整代码: