探索AJAX中的消息傳輸模式 (下)
在上一篇《探索AJAX中的消息傳輸模式 (上)》一文中,我主要介紹了普通字符串(Plain-text string)和XML格式的傳輸模式,然而在實際的開發(fā)應用中,這兩種方法基本上可以足夠應付我們的需求了,不過在對于復雜的對象傳輸?shù)臅r候,采用上面所介紹的這兩種傳輸模式有點顯得不理想。于此,本文將結合《探索AJAX中的消息傳輸模式(一) 》再介紹一種輕量級的數(shù)據(jù)交換格式JSON(JavaScript Object Notation) ,這是一種JavaScrpt自己的一種用來描述對象的方法,JSON從某個角度看可以說是XML的替代品。
在怎么使用JSON來進行數(shù)據(jù)傳輸之前,我們先來看看幾個簡單的JSON語法,為不熟悉JSON且想看本文的朋友打下基礎。JSON和XML一樣也是一種簡單文本格式。相對于XML,它更加易讀、更便于肉眼檢查。在語法的層面上,JSON與其他格式的區(qū)別是在于分隔數(shù)據(jù)的字符,JSON中的分隔符限于單引號、小括號、中括號、大括號、冒號和逗號。下面是一個JSON有效負載:
{"UserID":"0001","UserName":"ZhangSan","UserAge":"22"}
|
看起來是不是很簡單,鍵與值一一對應(Key----Value),下面我們看看一個復雜點的JSON有效負載:
{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> |
關于JSON更詳細的使用和語法格式請查看相關資料,這里我推薦一個網(wǎng)站(http://www.json.org/)。也可以在在園里搜索下園內前輩們的文章,Truly的《深入淺出JSON 》這篇文章就介紹了JSON,個人感覺介紹的很細致。
上面說了這么多,我們還是用一個示例來演示下JSON的使用,要不就成了紙上談兵了。 本文的是《探索AJAX中的消息傳輸模式 (上)》的續(xù)篇,示例代碼還是建立在此文的基礎上,在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)構造JSON字符串的時候多出來的,如果不移除方法的返回值則是下面這樣:

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

到此,服務端的工作算準備完畢,下面看看客戶端是如何實現(xiàn),首先為aspx頁面提供ScriptManager控件,然后引入WebService以便在客戶端調用WebService里的方法:
<asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="MessageWebService.asmx" /> </Services> </asp:ScriptManager> |
在提供一個下來列表控件來讓用戶選擇員工編號,這里通過設置默認值(在實際開發(fā)應用中可能會從數(shù)據(jù)庫里讀取數(shù)據(jù),這里只是為了做程序演示),通過一個按扭來發(fā)送請求,將結果顯示在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);
} |
當點擊按扭的時候就觸發(fā)click事件,調用onButtonClicked方法,執(zhí)行調用WebService里的方法:
function onButtonClicked(eventElement)
{
//取得選擇的員工ID
var employeeID = ddlEmployeeID.options[ddlEmployeeID.selectedIndex].value;
//調用WebService獲取數(shù)據(jù)
MessageWebService.GetEmployeeWithJson(employeeID,onJsonCallBack);
}
|
以異步的方式向服務端發(fā)起請求,把employeeID做為參數(shù)傳遞到服務器端,通過onJsonCallBack回調方法來處理返回的數(shù)據(jù),如下所示:
//根據(jù)返回的數(shù)據(jù)動態(tài)構造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>無標題頁</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;
//調用WebService獲取數(shù)據(jù)
MessageWebService.GetEmployeeWithJson(employeeID,onJsonCallBack);
}
function onJsonCallBack(text)
{
var data = eval("data="+text);
//服務端的WebService返回的是一個JSON字符串,上面的賦值后data的數(shù)據(jù)實際就等同于下面的定義
//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)構造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>
如上處理,如果服務器端無數(shù)據(jù)返回則在客戶端頁面上只輸出表頭信息。

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

【編輯推薦】

























