探索AJAX中的消息傳輸模式 (下)
在上一篇《探索AJAX中的消息傳輸模式 (上)》一文中,我主要介紹了普通字符串(Plain-text string)和XML格式的傳輸模式,然而在實(shí)際的開發(fā)應(yīng)用中,這兩種方法基本上可以足夠應(yīng)付我們的需求了,不過在對于復(fù)雜的對象傳輸?shù)臅r候,采用上面所介紹的這兩種傳輸模式有點(diǎn)顯得不理想。于此,本文將結(jié)合《探索AJAX中的消息傳輸模式(一) 》再介紹一種輕量級的數(shù)據(jù)交換格式JSON(JavaScript Object Notation) ,這是一種JavaScrpt自己的一種用來描述對象的方法,JSON從某個角度看可以說是XML的替代品。
在怎么使用JSON來進(jìn)行數(shù)據(jù)傳輸之前,我們先來看看幾個簡單的JSON語法,為不熟悉JSON且想看本文的朋友打下基礎(chǔ)。JSON和XML一樣也是一種簡單文本格式。相對于XML,它更加易讀、更便于肉眼檢查。在語法的層面上,JSON與其他格式的區(qū)別是在于分隔數(shù)據(jù)的字符,JSON中的分隔符限于單引號、小括號、中括號、大括號、冒號和逗號。下面是一個JSON有效負(fù)載:
{"UserID":"0001","UserName":"ZhangSan","UserAge":"22"}
 | 
看起來是不是很簡單,鍵與值一一對應(yīng)(Key----Value),下面我們看看一個復(fù)雜點(diǎn)的JSON有效負(fù)載:
{Employees:[
       {"EmployeeID":"1","LastName":"Davolio","City":"Seattle","Country":"USA"},
       {"EmployeeID":"2","LastName":"Fuller","City":"Tacoma","Country":"USA"}
           ]
}
 | 
從上面的JSON可以很清晰的看出,在Employees這個對象里包含有兩條數(shù)據(jù),我們將其用XML改寫,如下:
<?xml version='1.0' ?> <Employees> <Employee> <EmployeeID>1</EmployeeID> <LastName>Davolio</LastName> <City>Seattle</City> <Country>USA</Country> </Employee> <Employee> <EmployeeID>2</EmployeeID> <LastName>Fuller</LastName> <City>Tacoma</City> <Country>USA</Country> </Employee> <Employees>  | 
關(guān)于JSON更詳細(xì)的使用和語法格式請查看相關(guān)資料,這里我推薦一個網(wǎng)站(http://www.json.org/)。也可以在在園里搜索下園內(nèi)前輩們的文章,Truly的《深入淺出JSON 》這篇文章就介紹了JSON,個人感覺介紹的很細(xì)致。
上面說了這么多,我們還是用一個示例來演示下JSON的使用,要不就成了紙上談兵了。 本文的是《探索AJAX中的消息傳輸模式 (上)》的續(xù)篇,示例代碼還是建立在此文的基礎(chǔ)上,在WebService里添加一新方法提供根據(jù)員工編號(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 (++i == dt.Rows.Count)
        {
            json.Append("}]");
        }
        json.Append(",");
    }
    json.Append("}");
    result = json.ToString().Remove(json.Length - 2, 1);  //移除","
    result = result.Remove(result.Length - 3, 1);  //移除"}"
    return result;
}
DataAccess.GetEmpoyees(int id)方法定義:
public static DataTable GetEmployees(int id)
{
    string cmdText = "select EmployeeID,LastName,City,Country from Employees";
    cmdText += " where EmployeeID <= " + id;
    return Exce(cmdText); //執(zhí)行SQL返回DataTable
}
 | 
這里也許大家會有所疑問,為什么這方法后面要移除一個","和"}",這是在上面動態(tài)構(gòu)造JSON字符串的時候多出來的,如果不移除方法的返回值則是下面這樣:

為了使在客戶端通過JavaScript能夠正確的解吸此JSON,在返回值后面多出的一個","和"}"是必須去掉的,如下:

到此,服務(wù)端的工作算準(zhǔn)備完畢,下面看看客戶端是如何實(shí)現(xiàn),首先為aspx頁面提供ScriptManager控件,然后引入WebService以便在客戶端調(diào)用WebService里的方法:
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="MessageWebService.asmx" /> </Services> </asp:ScriptManager>  | 
在提供一個下來列表控件來讓用戶選擇員工編號,這里通過設(shè)置默認(rèn)值(在實(shí)際開發(fā)應(yīng)用中可能會從數(shù)據(jù)庫里讀取數(shù)據(jù),這里只是為了做程序演示),通過一個按扭來發(fā)送請求,將結(jié)果顯示在div(resultEmployee)里:
請選擇員工編號范圍小于(<)<asp:DropDownList ID="ddlEmployeeID" runat="server">
    <asp:ListItem>1</asp:ListItem>
    <asp:ListItem>2</asp:ListItem>
    <asp:ListItem>3</asp:ListItem>
    <asp:ListItem>4</asp:ListItem>
    <asp:ListItem>5</asp:ListItem>
    <asp:ListItem>6</asp:ListItem>
    <asp:ListItem>7</asp:ListItem>
    <asp:ListItem>8</asp:ListItem>
</asp:DropDownList>
<input id="Query" type="button" value="查 詢" /><br /><hr />
<div id="resultEmployee"></div>
 | 
同樣,我們需要初始化客戶端對控件的引用,以及為按扭添加執(zhí)行事件:
var ddlEmployeeID;
var divResult;
var buttonQuery;
    
function pageLoad()
{
   ddlEmployeeID = $get("<% = ddlEmployeeID.ClientID %>");
   divResult = $get("resultEmployee");
   buttonQuery = $get("Query");
   $addHandler(buttonQuery,"click",onButtonClicked);
   onButtonClicked(null);
} | 
當(dāng)點(diǎn)擊按扭的時候就觸發(fā)click事件,調(diào)用onButtonClicked方法,執(zhí)行調(diào)用WebService里的方法:
function onButtonClicked(eventElement)
{
    //取得選擇的員工ID
     var employeeID = ddlEmployeeID.options[ddlEmployeeID.selectedIndex].value;
    //調(diào)用WebService獲取數(shù)據(jù)
    MessageWebService.GetEmployeeWithJson(employeeID,onJsonCallBack);
}
 | 
以異步的方式向服務(wù)端發(fā)起請求,把employeeID做為參數(shù)傳遞到服務(wù)器端,通過onJsonCallBack回調(diào)方法來處理返回的數(shù)據(jù),如下所示:
//根據(jù)返回的數(shù)據(jù)動態(tài)構(gòu)造html表格
var html = new Sys.StringBuilder();
html.append("<table width='460px' cellspacing='1' cellpadding='2' border='0' bgcolor='#999999'>");
html.append("<tr>");
html.append("<td bgcolor='gold' align='center'><b>EmployeeID</b></td>");
html.append("<td bgcolor='gold' align='center'><b>LastName</b></td>");
html.append("<td bgcolor='gold' align='center'><b>City</b></td>");
html.append("<td bgcolor='gold' align='center'><b>Country</b></td>");
html.append("</tr>");
       
for (var i=0;i< data.Employees.length;i++)
{  
    html.append("<tr>");
    html.append("<td bgcolor='white'>"+data.Employees[i]["EmployeeID"]+"</td>");
    html.append("<td bgcolor='white'>"+data.Employees[i].LastName+"</td>");
    html.append("<td bgcolor='white'>"+data.Employees[i].City+"</td>");
    html.append("<td bgcolor='white'>"+data.Employees[i].Country+"</td>");
    html.append("</tr>");
}
html.append("</table>");
resultEmployee.innerHTML = html.toString();
客戶端的完整代碼:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxMessageJson.aspx.cs" Inherits="AjaxMessageJson" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>無標(biāo)題頁</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
          <Services>
            <asp:ServiceReference Path="MessageWebService.asmx" />
          </Services>
        </asp:ScriptManager>
    <%--d--%>
    </div>
        請選擇員工編號范圍小于(<)<asp:DropDownList ID="ddlEmployeeID" runat="server">
            <asp:ListItem>1</asp:ListItem>
            <asp:ListItem>2</asp:ListItem>
            <asp:ListItem>3</asp:ListItem>
            <asp:ListItem>4</asp:ListItem>
            <asp:ListItem>5</asp:ListItem>
            <asp:ListItem>6</asp:ListItem>
            <asp:ListItem>7</asp:ListItem>
            <asp:ListItem>8</asp:ListItem>
        </asp:DropDownList>
                 
        <input id="Query" type="button" value="查 詢" /><br /><hr />
        <div id="resultEmployee"></div>
    </form>
    
    <script type="text/javascript">
    
    var ddlEmployeeID;
    var divResult;
    var buttonQuery;
    
    function pageLoad()
    {
       ddlEmployeeID = $get("<% = ddlEmployeeID.ClientID %>");
       divResult = $get("resultEmployee");
       buttonQuery = $get("Query");
       $addHandler(buttonQuery,"click",onButtonClicked);
       onButtonClicked(null);
    }
    
    function onButtonClicked(eventElement)
    {
       //取得選擇的員工ID
       var employeeID = ddlEmployeeID.options[ddlEmployeeID.selectedIndex].value;
       //調(diào)用WebService獲取數(shù)據(jù)
       MessageWebService.GetEmployeeWithJson(employeeID,onJsonCallBack);
    }
    
    function onJsonCallBack(text)
    {
       var data = eval("data="+text);          
       //服務(wù)端的WebService返回的是一個JSON字符串,上面的賦值后data的數(shù)據(jù)實(shí)際就等同于下面的定義            
       //var data = {Employees:[{"EmployeeID":"1","LastName":"Davolio","City":"Seattle","Country":"USA"},
       //            {"EmployeeID":"2","LastName":"Fuller","City":"Tacoma","Country":"USA"},
       //            {"EmployeeID":"3","LastName":"Leverling","City":"Kirkland","Country":"USA"}]};
       //
       
       //根據(jù)返回的數(shù)據(jù)動態(tài)構(gòu)造html表格
       var html = new Sys.StringBuilder();
       html.append("<table width='460px' cellspacing='1' cellpadding='2' border='0' bgcolor='#999999'>");
       html.append("<tr>");
       html.append("<td bgcolor='gold' align='center'><b>EmployeeID</b></td>");
       html.append("<td bgcolor='gold' align='center'><b>LastName</b></td>");
       html.append("<td bgcolor='gold' align='center'><b>City</b></td>");
       html.append("<td bgcolor='gold' align='center'><b>Country</b></td>");
       html.append("</tr>");
       
       for (var i=0;i< data.Employees.length;i++)
       {  
          html.append("<tr>");
          html.append("<td bgcolor='white'>"+data.Employees[i]["EmployeeID"]+"</td>");
          html.append("<td bgcolor='white'>"+data.Employees[i].LastName+"</td>");
          html.append("<td bgcolor='white'>"+data.Employees[i].City+"</td>");
          html.append("<td bgcolor='white'>"+data.Employees[i].Country+"</td>");
          html.append("</tr>");
       }
       html.append("</table>");
       resultEmployee.innerHTML = html.toString();
    }
    </script>
</body>
</html>
如上處理,如果服務(wù)器端無數(shù)據(jù)返回則在客戶端頁面上只輸出表頭信息。

如果有數(shù)據(jù)返回,則動態(tài)的構(gòu)造了表格并顯示在頁面上,如下:

【編輯推薦】















 
 
 







 
 
 
 