当前位置:沸点梦工场 > 网页编程 > Ajax教程 > 浏览文章

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

博客园 2008年06月25日 【字体:
在上一篇《探索AJAX中的消息传输模式(一) 》一文中,我主要介绍了普通字符串(Plain-text string)和XML格式的传输模式,然而在实际的开发应用中,这两种方法基本上可以足够应付我们的需求了,不过在对于复杂的对象传输的时候,采用上面所介绍的这两种传输模式有点显得不理想。于此,本文将结合《探索AJAX中的消息传输模式(一) 》再介绍一种轻量级的数据交换格式JSON(Javascript Object Notation) ,这是一种JavaScrpt自己的一种用来描述对象的方法,JSON从某个角度看可以说是XML的替代品。

      在怎么使用JSON来进行数据传输之前,我们先来看看几个简单的JSON语法,为不熟悉JSON且想看本文的朋友打下基础。JSON和XML一样也是一种简单文本格式。相对于XML,它更加易读、更便于肉眼检查。在语法的层面上,JSON与其他格式的区别是在于分隔数据的字符,JSON中的分隔符限于单引号、小括号、中括号、大括号、冒号和逗号。下面是一个JSON有效负载:

点此在新窗口浏览图片{"UserID":"0001","UserName":"ZhangSan","UserAge":"22"}

     看起来是不是很简单,键与值一一对应(Key----Value),下面我们看看一个复杂点的JSON有效负载:

1点此在新窗口浏览图片{Employees:[
2点此在新窗口浏览图片       {"EmployeeID":"1","LastName":"Davolio","City":"Seattle","Country":"USA"},
3点此在新窗口浏览图片       {"EmployeeID":"2","LastName":"Fuller","City":"Tacoma","Country":"USA"}
4点此在新窗口浏览图片           ]
5点此在新窗口浏览图片}
   
     从上面的JSON可以很清晰的看出,在Employees这个对象里包含有两条数据,我们将其用XML改写,如下:
 1点此在新窗口浏览图片<?xml version='1.0' ?>
 2点此在新窗口浏览图片<Employees>
 3点此在新窗口浏览图片  <Employee>
 4点此在新窗口浏览图片     <EmployeeID>1</EmployeeID>
 5点此在新窗口浏览图片     <LastName>Davolio</LastName>
 6点此在新窗口浏览图片     <City>Seattle</City>
 7点此在新窗口浏览图片     <Country>USA</Country>
 8点此在新窗口浏览图片  </Employee>
 9点此在新窗口浏览图片  <Employee>
10点此在新窗口浏览图片    <EmployeeID>2</EmployeeID>
11点此在新窗口浏览图片    <LastName>Fuller</LastName>
12点此在新窗口浏览图片    <City>Tacoma</City>
13点此在新窗口浏览图片    <Country>USA</Country>
14点此在新窗口浏览图片  </Employee>
15点此在新窗口浏览图片<Employees>

      关于JSON更详细的使用和语法格式请查看相关资料,这里我推荐一个网站(http://www.json.org/)。也可以在在园里搜索下园内前辈们的文章,Truly的《深入浅出JSON 》这篇文章就介绍了JSON,个人感觉介绍的很细致。

     上面说了这么多,我们还是用一个示例来演示下JSON的使用,要不就成了纸上谈兵了。 本文的是《探索AJAX中的消息传输模式(一) 》的续篇,示例代码还是建立在此文的基础上,在WebService里添加一新方法提供根据员工编号(EmployeeID)查询小于等于(<=)该编号的所用员工信息:

点此在新窗口浏览图片[WebMethod]
点此在新窗口浏览图片
public string GetEmployeeWithJson(int id)
点此在新窗口浏览图片点此在新窗口浏览图片
{
点此在新窗口浏览图片    
//查询出EmployeeID,LastName,City,Country四个字段
点此在新窗口浏览图片
    DataTable dt = DataAccess.GetEmployees(id);
点此在新窗口浏览图片    StringBuilder json 
= new StringBuilder();
点此在新窗口浏览图片    json.Append(
"{Employees:[");
点此在新窗口浏览图片
点此在新窗口浏览图片    
int i = 0;
点此在新窗口浏览图片    
string result = string.Empty;
点此在新窗口浏览图片    
foreach (DataRow row in dt.Rows)
点此在新窗口浏览图片点此在新窗口浏览图片    
{
点此在新窗口浏览图片        json.Append(
"{");
点此在新窗口浏览图片        json.Append(
@"""EmployeeID"":""" + row["EmployeeID"+ @""",");
点此在新窗口浏览图片        json.Append(
@"""LastName"":""" + row["LastName"+ @""",");
点此在新窗口浏览图片        json.Append(
@"""City"":""" + row["City"+ @""",");
点此在新窗口浏览图片        json.Append(
@"""Country"":""" + row["Country"+ @"""}");
点此在新窗口浏览图片
点此在新窗口浏览图片        
if (++== dt.Rows.Count)
点此在新窗口浏览图片点此在新窗口浏览图片        
{
点此在新窗口浏览图片            json.Append(
"}]");
点此在新窗口浏览图片        }

点此在新窗口浏览图片        json.Append(
",");
点此在新窗口浏览图片    }

点此在新窗口浏览图片    json.Append(
"}");
点此在新窗口浏览图片    result 
= json.ToString().Remove(json.Length - 21);  //移除","
点此在新窗口浏览图片
    result = result.Remove(result.Length - 31);  //移除"}"
点此在新窗口浏览图片
    return result;
点此在新窗口浏览图片}
点此在新窗口浏览图片点此在新窗口浏览图片DataAccess.GetEmpoyees(int id)方法定义

     这里也许大家会有所疑问,为什么这方法后面要移除一个","和"}",这是在上面动态构造JSON字符串的时候多出来的,如果不移除方法的返回值则是下面这样:点此在新窗口浏览图片
    为了使在客户端通过Javascript能够正确的解吸此JSON,在返回值后面多出的一个","和"}"是必须去掉的,如下:点此在新窗口浏览图片
    到此,服务端的工作算准备完毕,下面看看客户端是如何实现,首先为aspx页面提供scriptManager控件,然后引入WebService以便在客户端调用WebService里的方法:
1点此在新窗口浏览图片<asp:scriptManager ID="scriptManager1" runat="server">
2点此在新窗口浏览图片  <Services>
3点此在新窗口浏览图片    <asp:ServiceReference Path="MessageWebService.asmx" />
4点此在新窗口浏览图片  </Services>
5点此在新窗口浏览图片</asp:scriptManager>

    在提供一个下来列表控件来让用户选择员工编号,这里通过设置默认值(在实际开发应用中可能会从数据库里读取数据,这里只是为了做程序演示),通过一个按扭来发送请求,将结果显示在div(resultEmployee)里:
 1点此在新窗口浏览图片请选择员工编号范围小于(<)<asp:DropDownList ID="ddlEmployeeID" runat="server">
 2点此在新窗口浏览图片    <asp:ListItem>1</asp:ListItem>
 3点此在新窗口浏览图片    <asp:ListItem>2</asp:ListItem>
 4点此在新窗口浏览图片    <asp:ListItem>3</asp:ListItem>
 5点此在新窗口浏览图片    <asp:ListItem>4</asp:ListItem>
 6点此在新窗口浏览图片    <asp:ListItem>5</asp:ListItem>
 7点此在新窗口浏览图片    <asp:ListItem>6</asp:ListItem>
 8点此在新窗口浏览图片    <asp:ListItem>7</asp:ListItem>
 9点此在新窗口浏览图片    <asp:ListItem>8</asp:ListItem>
10点此在新窗口浏览图片</asp:DropDownList>
11点此在新窗口浏览图片
12点此在新窗口浏览图片<input id="Query" type="button" value="查 询" /><br /><hr />
13点此在新窗口浏览图片<div id="resultEmployee"></div>

    同样,我们需要初始化客户端对控件的引用,以及为按扭添加执行事件:
 1点此在新窗口浏览图片var ddlEmployeeID;
 2点此在新窗口浏览图片var divResult;
 3点此在新窗口浏览图片var buttonQuery;
 4点此在新窗口浏览图片    
 5点此在新窗口浏览图片function pageLoad()
 6点此在新窗口浏览图片点此在新窗口浏览图片{
 7点此在新窗口浏览图片   ddlEmployeeID = $get("<% = ddlEmployeeID.ClientID %>");
 8点此在新窗口浏览图片   divResult = $get("resultEmployee");
 9点此在新窗口浏览图片   buttonQuery = $get("Query");
10点此在新窗口浏览图片   $addHandler(buttonQuery,"click",onButtonClicked);
11点此在新窗口浏览图片   onButtonClicked(null);
12点此在新窗口浏览图片}

     当点击按扭的时候就触发click事件,调用onButtonClicked方法,执行调用WebService里的方法:
1点此在新窗口浏览图片function onButtonClicked(eventElement)
2点此在新窗口浏览图片点此在新窗口浏览图片{
3点此在新窗口浏览图片    //取得选择的员工ID
4点此在新窗口浏览图片     var employeeID = ddlEmployeeID.options[ddlEmployeeID.selectedIndex].value;
5点此在新窗口浏览图片    //调用WebService获取数据
6点此在新窗口浏览图片    MessageWebService.GetEmployeeWithJson(employeeID,onJsonCallBack);
7点此在新窗口浏览图片}

    以异步的方式向服务端发起请求,把employeeID做为参数传递到服务器端,通过onJsonCallBack回调方法来处理返回的数据,如下所示:
 1点此在新窗口浏览图片//根据返回的数据动态构造html表格
 2点此在新窗口浏览图片var html = new Sys.StringBuilder();
 3点此在新窗口浏览图片html.append("<table width='460px' cellspacing='1' cellpadding='2' border='0' bgcolor='#999999'>");
 4点此在新窗口浏览图片html.append("<tr>");
 5点此在新窗口浏览图片html.append("<td bgcolor='gold' align='center'><b>EmployeeID</b></td>");
 6点此在新窗口浏览图片html.append("<td bgcolor='gold' align='center'><b>LastName</b></td>");
 7点此在新窗口浏览图片html.append("<td bgcolor='gold' align='center'><b>City</b></td>");
 8点此在新窗口浏览图片html.append("<td bgcolor='gold' align='center'><b>Country</b></td>");
 9点此在新窗口浏览图片html.append("</tr>");
10点此在新窗口浏览图片       
11点此在新窗口浏览图片for (var i=0;i< data.Employees.length;i++)
12点此在新窗口浏览图片点此在新窗口浏览图片{  
13点此在新窗口浏览图片    html.append("<tr>");
14点此在新窗口浏览图片    html.append("<td bgcolor='white'>"+data.Employees[i]["EmployeeID"]+"</td>");
15点此在新窗口浏览图片    html.append("<td bgcolor='white'>"+data.Employees[i].LastName+"</td>");
16点此在新窗口浏览图片    html.append("<td bgcolor='white'>"+data.Employees[i].City+"</td>");
17点此在新窗口浏览图片    html.append("<td bgcolor='white'>"+data.Employees[i].Country+"</td>");
18点此在新窗口浏览图片    html.append("</tr>");
19点此在新窗口浏览图片}

20点此在新窗口浏览图片html.append("</table>");
21点此在新窗口浏览图片resultEmployee.innerHTML = html.toString();
点此在新窗口浏览图片点此在新窗口浏览图片客户端的完整代码