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

来源:互联网 发布:软件漏洞挖掘教程 编辑:程序博客网 时间:2024/05/20 23:59
转自:博客园 blogs.com/  beniao的博客http://www.cnblogs.com/beniao/archive/2008/06/23/1206968.html
探索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">

       用户通过点击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]  4public 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类里:
1str = new StringBuilder(); 2str.Append("<span style="+"font-weight:bold;font-size:20;color:Red;>"); 3str.Append("带有HTML的字符串,返回此字符串,所拥有的样式等都可以得到解析!"); 4str.Append("</span>"); 5HTML = str.ToString();
      类里所封装的html对应的字符传是带有css样式及html标识的字符串,返回这个html字符串那客户端是否能得到解析??答案是肯定的,这里只是做到了用户点击相应的连接就发送请求到服务器,要使这个应用完善,我们还得为这个应用初始化一个显示值:
1public 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]  2public 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//回调函数  2function 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        所要显示的列 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  18        &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  19        方式字段 &nbsp; &nbsp;&nbsp; 提取记录行数<br />  20        <asp:CheckBox ID="cbID" runat="server" Text="ID" />  21        &nbsp;  22        <asp:CheckBox ID="cbLastName" runat="server" Text="LastName" />  23        &nbsp;  24        <asp:CheckBox ID="cbCity" runat="server" Text="City" />  25        &nbsp; &nbsp;  26        <asp:CheckBox ID="cbCountry" runat="server" Text="Country" />  27        &nbsp;  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        &nbsp; &nbsp; &nbsp;<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        &nbsp;&nbsp;  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中的消息传输模式(二)

Tag标签: ajax,xml,WebService,C#,asp.net
原创粉丝点击