转自:博客园 blogs.
com/
beniao的博客 http://www.cnblogs.com/beniao/archive/2008/06/23/1206968.html
在我们使用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类来封装这些数据,详细代码定义如下:
1/// <summary> 2/// Message 的摘要说明 3/// </summary> 4public 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表为例,根据客户端的条件(排序字段,提取的记录条数)查询数据库,下面是数据库访问代码:
1public 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中的消息传输模式(二)