摘要
本文將首先介紹一下文章的寫作背景和用到的相關(guān)技術(shù)。然后將分別使用樸素的Ajax技術(shù)和ASP.NET AJAX框架分別實(shí)現(xiàn)經(jīng)典的“Hello!XX”,通過兩個(gè)小例子,使朋友們對這個(gè)框架的特點(diǎn)和框架的使用方法有一個(gè)初步的認(rèn)識。
前言
我想,如果今天哪個(gè)Web開發(fā)人員說沒有聽說過Ajax技術(shù),那實(shí)在太不可思議了。確實(shí),近幾年,Ajax這個(gè)詞以超乎想象的速度紅遍Web開發(fā)領(lǐng)域,大到Google、網(wǎng)易,小到一些地方公司的主頁,都普遍開始加入Ajax元素。這種技術(shù),給Web開發(fā)帶來了革命性的意義,也使得Web產(chǎn)品及B/S系統(tǒng)的用戶體驗(yàn)大大改善。
然而,Ajax用起來華麗、爽快,開發(fā)起來卻困難重重。JavaScript語言怪異的語法、沒有IDE支持以及難以調(diào)試,都成為Ajax開發(fā)的硬傷。另外B/S系統(tǒng)和C/S不同,瀏覽器的多樣性也給Ajax的開發(fā)帶來很多困難,使得我們在做Ajax應(yīng)用時(shí),不得不考慮到各種瀏覽器的差異,開發(fā)過程痛苦至極。
針對這種情況,各種Ajax框架應(yīng)運(yùn)而生。這其中的佼佼者,便是微軟推出的ASP.NET AJAX框架。它不僅給使得開發(fā)Ajax應(yīng)用變得容易很多,而且更可以與微軟的開發(fā)工具無縫集成,給.NET平臺(tái)的開發(fā)人員帶來很大方便。
這一系列文章,就是要介紹這個(gè)框架的客戶端編程。
ASP.NET AJAX能做什么?
ASP.NET AJAX框架帶來的好處和特性實(shí)在太多了,這里簡要列幾條:
1.擴(kuò)展了JavaScript語言,增加了面向?qū)ο筇匦?。簡化了一些DOM操作的語法。
2.一系列的服務(wù)器端控件可以讓程序員不編寫JS,而僅通過拖控件完成Ajax應(yīng)用的開發(fā)。
3.開創(chuàng)性的提出了客戶端組件、行為組件等概念,并提供了一種類似XML的標(biāo)簽式語言,給Ajax客戶端編寫帶來革命性創(chuàng)新。
4.完善的代理模型機(jī)制,使得開發(fā)人員可以在JS中直接調(diào)用后臺(tái)程序,就像在后臺(tái)調(diào)用一樣。
5.各種數(shù)據(jù)類型的自動(dòng)轉(zhuǎn)換,特別是對于復(fù)雜類型,內(nèi)置自動(dòng)序列化和反序列化機(jī)制,是的前后臺(tái)可以直接共用復(fù)雜類型,而不必手工轉(zhuǎn)換。
6.提供了大量的客戶端組件,方便程序開發(fā)。
7.屏蔽了瀏覽器之間的差異,讓開發(fā)人員可以不再處理那些令人頭疼的瀏覽器差異問題。
服務(wù)器端編程 VS 客戶端編程
ASP.NET AJAX框架提供了兩種開發(fā)模型:服務(wù)器端編程和客戶端編程。前者使用方便,開發(fā)人員可以不懂JS和Ajax,而是通過傳統(tǒng)的ASP.NET開發(fā)方式完成Ajax應(yīng)用的開發(fā),但是其控制粒度較粗。而后者開發(fā)難度相對較大,需要開發(fā)人員熟悉JavaScript,并熟悉ASP.NET AJAX提供的各種語法支持及客戶端編程模型,但是其控制粒度精細(xì),有利于提高應(yīng)用的性能和質(zhì)量。
本系列文章將重點(diǎn)介紹客戶端編程。
開始ASP.NET AJAX之旅:讓我們一起對ASP.NET AJAX說Hello!
下面,我將分別用兩種方式實(shí)現(xiàn)一個(gè)最簡單的Ajax應(yīng)用:單擊按鈕,異步調(diào)用后臺(tái)類中的一個(gè)方法,返回一個(gè)字符串,顯示在頁面指定位置,整個(gè)過程不刷新頁面。其效果圖如下:
左圖為單擊前,右圖為單擊后。整個(gè)過程頁面無刷新,所顯示的字符串是從后臺(tái)程序得到的。下面,將用兩種方法實(shí)現(xiàn)這個(gè)小應(yīng)用。
沒有ASP.NET AJAX的日子:想說Hello不容易!很難很費(fèi)力!
首先,我們不使用任何框架,手工創(chuàng)建這個(gè)Ajax應(yīng)用。
1.創(chuàng)建工程
打開VS(我用的是2005),創(chuàng)建一個(gè)新的Website,命名為AjaxTest。完成后,添加系統(tǒng)文件夾App_Code。
2.創(chuàng)建后臺(tái)程序
下面我們要編寫供前臺(tái)調(diào)用的后臺(tái)程序,這個(gè)程序很簡單,只需要返回一個(gè)字符串。我們在App_Code文件夾下添加一個(gè)新的文件Hello.cs,這是個(gè)C#類文件,其詳細(xì)代碼如下:
Hello.cs:
1using System;
2
3public class Hello
4{
5 public Hello() { }
6
7 public string SayHello()
8 {
9 return "Hello!Ajax";
10 }
11}
代碼沒有什么好解釋的,只有一個(gè)方法,就是返回“Hello!Ajax”這個(gè)字符串。
3.創(chuàng)建后臺(tái)頁面
只有一個(gè)類是不成的,Ajax最終要調(diào)用一個(gè)頁面,所以,這里還需要做一個(gè)aspx頁面供前臺(tái)直接調(diào)用。在網(wǎng)站工程下新建一個(gè)文件Output.aspx,將其中的所有代碼都刪除,只保留第一行。因?yàn)槲覀儾恍枰暾@示這個(gè)頁面,只是要它返回一行字符串。
Output.aspx:
1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Output.aspx.cs" Inherits="Output" %>
然后,我們需要在這個(gè)頁面的Page_Load事件中調(diào)用Hello類的SayHello方法,并使用Response.Write方法將其輸出。
Output.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11
12public partial class Output : System.Web.UI.Page
13{
14 protected void Page_Load(object sender, EventArgs e)
15 {
16 Hello myHello = new Hello();
17 Response.Write(myHello.SayHello());
18 }
19}
4.編寫JavaScript腳本
我們的主角終于要登場了。讓我們開始編寫Ajax代碼。首先在網(wǎng)站工程下新建ajax.js文件,這個(gè)文件將包含Ajax核心代碼,具體內(nèi)容如下:
ajax.js:
1var xmlHttp;//全局XMLHttpResquest對象
2
3//針對不同瀏覽器,獲取XMLHttpRequest對象
4function CreateXMLHttpRequest()
5{
6 if(window.ActiveXObject)
7 {
8 xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
9 }
10 else
11 {
12 xmlHttp=new XMLHttpResquest();
13 }
14}
15
16//單擊btnSayHello時(shí)調(diào)用的JS函數(shù)
17function btnSayHello_onClick()
18{
19 CreateXMLHttpRequest();
20 xmlHttp.onreadystatechange=HandleStateChange;
21 xmlHttp.open("POST","Output.aspx",true);
22 xmlHttp.send(null);
23}
24
25//回調(diào)函數(shù)
26function HandleStateChange()
27{
28 if(xmlHttp.readyState==4)
29 {
30 if(xmlHttp.status==200)
31 {
32 document.getElementById("result").innerHTML = xmlHttp.responseText;
33 }
34 }
35}
下面我對這個(gè)代碼進(jìn)行一個(gè)簡要的解釋。
首先,xmlHttp是一個(gè)全局變量,它被初始化后,將負(fù)責(zé)整個(gè)Ajax應(yīng)用的核心。CreateXMLHttpRequest方法用來得到XMLHttpRequest對象的實(shí)例,這里我們注意到,由于不同瀏覽器的獲取對象方法不同,這里首先要檢測瀏覽器類型,然后使用相應(yīng)方法獲得對象,十分麻煩。btnSayHello_onClick是一個(gè)核心函數(shù),當(dāng)按鈕被單擊時(shí),將調(diào)用這個(gè)函數(shù)。它首先初始化xmlHttp,然后指定回調(diào)函數(shù)為HandleStateChange,最后異步發(fā)布POST請求,調(diào)用Output.aspx頁面。最后,HandleStateChange作為回調(diào)函數(shù),在xmlHttp的請求狀態(tài)發(fā)生改變時(shí)將自動(dòng)被調(diào)用。而在這個(gè)函數(shù)中,當(dāng)狀態(tài)正常時(shí),將id為“result”的DIV的內(nèi)容設(shè)為調(diào)用結(jié)果。即Output.aspx輸出的字符串。
5.主頁
最后,當(dāng)然我們要制作主要頁面。在這里我直接使用Default.aspx,其代碼如下:
Defualt.aspx:
1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
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>Hello!Ajax http://www.dwww.cn</title>
8 <script src="ajax.js" type="text/javascript"></script>
9</head>
10<body>
11 <form id="form1" runat="server">
12 <div>
13 <input id="btnSayHello" type="button" value="SayHello" onclick="btnSayHello_onClick()" />
14 <div id="result"></div>
15 </div>
16 </form>
17</body>
18</html>
這里將ajax.js作為外部腳本引入,讓后讓btnSayHello的onclick事件與btnSayHello_onClick關(guān)聯(lián)。而result這個(gè)DIV則用于顯示結(jié)果。
現(xiàn)在運(yùn)行Default.aspx,點(diǎn)擊SayHello按鈕,即可看到效果。
使用ASP.NET AJAX:讓Hello說的輕松一點(diǎn)
可以看出,在上面的實(shí)現(xiàn)過程中,JS腳本非常麻煩,不僅要處理各種瀏覽器的差別(其實(shí)我上面的代碼還沒有照顧到所有瀏覽器),還要在回調(diào)函數(shù)中判斷相應(yīng)狀態(tài)。調(diào)用過程也必須手工進(jìn)行。那么,我們可不可以在JS中直接調(diào)用后臺(tái)代碼中的某個(gè)方法呢?就像在后臺(tái)調(diào)用一樣。答案是肯定的,只要我們使用ASP.NET AJAX。
ASP.NET AJAX框架在VS2008中是自帶的,但如果你和我一樣使用的是VS2005和.net framework2.0和話,則需要手工安裝。在微軟官方網(wǎng)站有下載,安裝過程也和普通軟件安裝很相似,這里不再贅述。
下面,我們使用ASP.NET AJAX框架再次實(shí)現(xiàn)這個(gè)應(yīng)用。
1.創(chuàng)建工程
這一次,我們還是需要?jiǎng)?chuàng)建一個(gè)新的網(wǎng)站,不同的是,我們選擇ASP.NET AJAX-Enabled Web Site,使用這個(gè)項(xiàng)目創(chuàng)建網(wǎng)站后,VS將自動(dòng)在Web.config中配置好這個(gè)框架需要的配置項(xiàng),而且會(huì)在頁面中自動(dòng)加入一個(gè)ScriptManager控件,這個(gè)控件是ASP.NET AJAX應(yīng)用所必不可少的。創(chuàng)建完成后,仍需要新建App_Code文件夾。
2.創(chuàng)建后臺(tái)程序
這個(gè)和上一部分的后臺(tái)程序非常類似,仍是在App_Code文件夾下建立Hello.cs,代碼如下:
Hello.cs:
1using System;
2
3public class Hello
4{
5 public Hello() { }
6
7 public string SayHello()
8 {
9 return "Hello!ASP.NET AJAX";
10 }
11}
3.創(chuàng)建WebService
其實(shí),使用ASP.NET AJAX框架后,JS是可以直接調(diào)用后臺(tái)類中的方法的,但是這里不建議這樣做,而是使用WebService作為過渡,讓JS調(diào)用WebService。關(guān)于其中的理由,將在以后介紹。
在網(wǎng)站工程下新建WebService文件SayHelloService,這時(shí)VS會(huì)自動(dòng)在App_Code文件夾下建立對應(yīng)的代碼文件,SayHelloService.cs,具體程序代碼如下:
SayHelloService.cs:
1using System;
2using System.Web;
3using System.Collections;
4using System.Web.Services;
5using System.Web.Services.Protocols;
6using System.Web.Script.Services;
7
8[WebService(Namespace = "http://tempuri.org/")]
9[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
10[ScriptService]
11public class SayHelloService : System.Web.Services.WebService
12{
13 public SayHelloService() { }
14
15 [WebMethod]
16 public string SayHello()
17 {
18 Hello myHello = new Hello();
19 return myHello.SayHello();
20 }
21}
22
其中要特別注意三個(gè)地方,一個(gè)是using Web.Script.Services,這里必須引入這個(gè)命名空間。然后就是SayHelloService類上面的[ScriptService]屬性(Attribute)和SayHello方法上面的[WebMethod]屬性,這兩個(gè)屬性對于JS的訪問是不可缺少的。
4.編寫JavaScript
這時(shí),ajax.js文件的代碼如下:
ajax.js:
1//單擊btnSayHello時(shí)調(diào)用的JS函數(shù)
2function btnSayHello_onClick()
3{
4 SayHelloService.SayHello(HandleStateChange);
5}
6
7//回調(diào)函數(shù)
8function HandleStateChange(reusltText)
9{
10 get("result").innerHTML=reusltText;
11}
這里我們看到了神奇的事情:35行JS代碼變成了11行,并且這里直接使用了SayHelloService.SayHello()這樣的方法,這個(gè)方法是定義在SayHelloService.cs里的,而在這里的JS中就像在后臺(tái)一樣,直接調(diào)用了這個(gè)方法,并不需要?jiǎng)?chuàng)建對象、發(fā)送請求等一大套東西。這里也不用擔(dān)心瀏覽器差別問題,因?yàn)檫@個(gè)框架已經(jīng)為我們屏蔽了瀏覽器差異。
而且回調(diào)函數(shù)中,不需要判斷狀態(tài)了,因?yàn)锳SP.NET AJAX自動(dòng)分開了成功時(shí)調(diào)用的回調(diào)函數(shù)和失敗時(shí)調(diào)用的回調(diào)函數(shù)。而且這里用“get”代替了“getElementById”,這也是這個(gè)框架給我們提供的便利。
5.主頁
現(xiàn)在我們再看看主頁代碼:
Default.aspx:
1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page http://dwww.cn</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <asp:ScriptManager ID="ScriptManager1" runat="server">
11 <Scripts>
12 <asp:ScriptReference Path="~/ajax.js" />
13 </Scripts>
14 <Services>
15 <asp:ServiceReference Path="~/SayHelloService.asmx" />
16 </Services>
17 </asp:ScriptManager>
18 <div>
19 <input id="btnSayHello" type="button" value="SayHello" onclick="btnSayHello_onClick()" />
20 <div id="result"></div>
21 </div>
22 </form>
23</body>
24</html>
可以看到,唯一變化就是多了一個(gè)ScriptManager控件,這是使用ASP.NET AJAX框架必須引入的控件。控件中還定義了需要引入的外部JS腳本文件和WebService文件。
現(xiàn)在運(yùn)行Default.aspx,也達(dá)到了同樣效果。
結(jié)束語
我想通過上面的兩個(gè)例子,應(yīng)該能從感性層面上體會(huì)到ASP.NET AJAX這個(gè)框架的一些特性及優(yōu)勢。當(dāng)然,其特性還遠(yuǎn)不止這些,像實(shí)體類的自動(dòng)序列化和反序列化、客戶端組件等一系列內(nèi)容,將在后續(xù)章節(jié)討論。
這里也沒有對技術(shù)進(jìn)行細(xì)致講解,意在使朋友們將注意力集中在對這個(gè)框架的感性理解上。后續(xù)文章會(huì)對一些技術(shù)性問題進(jìn)行講述。
文中的兩個(gè)小例子可以在這里下載:AjaxTest.rar ASPNETAJAXTest.rar
主要參考文獻(xiàn)
[1] 陳黎夫,ASP.NET AJAX程序設(shè)計(jì)-第II卷:客戶端,人民郵電出版社,2007年10月
[2] Ryan Asleson等,Ajax基礎(chǔ)教程,人民郵電出版社,2006年2月
來源:http://www.cnblogs.com/leoo2sk