在ASP.NET中使用AJAX的簡(jiǎn)單方法

2010-08-28 10:54:03來(lái)源:西部e網(wǎng)作者:

  據(jù)我所知,這項(xiàng)技術(shù)最初是由Microsoft在1999年提出來(lái)的,也就是我們所熟知的"使用遠(yuǎn)程調(diào)用(remote calls)的DHTML / JavaScript web應(yīng)用程序"。這項(xiàng)技術(shù)的核心就是通過(guò)瀏覽器發(fā)出一個(gè)異步的HTTP請(qǐng)求來(lái)調(diào)用服務(wù)端的網(wǎng)頁(yè)或服務(wù),在返回結(jié)果后,無(wú)需刷新就可以更新整個(gè)網(wǎng)頁(yè)。這項(xiàng)技術(shù)經(jīng)過(guò)不斷地完善,到目前為此,使用AJAX的web程序從表現(xiàn)上看已經(jīng)非常類似于Windows程序了。

  由于這項(xiàng)技術(shù)的實(shí)現(xiàn)需要依賴于前端的瀏覽器,因此,它的使用受到了限制。但在最近的幾年,由于瀏覽器功能的加強(qiáng)和一些公司,如Google、Amazon.com的許多基于AJAX的應(yīng)用的不俗表現(xiàn),終于使這項(xiàng)技術(shù)鳳凰涅磐、欲火重生。

  現(xiàn)在AJAX的使用已經(jīng)非常廣泛,任何帶有豐富用戶體驗(yàn)的動(dòng)態(tài)網(wǎng)頁(yè)都會(huì)不約而同地使用AJAX。

  解決方案

  本文所描述的使用AJAX的方法非常簡(jiǎn)單,而且效率很高。同時(shí)這種方法還非常容易維護(hù),并且開發(fā)人員無(wú)需任何的特殊技巧就可以實(shí)現(xiàn)它,而且使用這種方法還可以跨瀏覽器。

  一個(gè)基本的AJAX實(shí)現(xiàn)需要兩個(gè)主要部分:一個(gè)使用JavaScript代碼編寫的客戶端HTML頁(yè),這些JavaScript用來(lái)向服務(wù)端發(fā)送請(qǐng)求和接收響應(yīng);一個(gè)可以接收請(qǐng)求和向客戶端發(fā)送響應(yīng)信息的遠(yuǎn)程頁(yè)面?蛻舳说腏avaScript代碼的任務(wù)是建立一個(gè)XmlHttp對(duì)象,然后向服務(wù)端發(fā)送請(qǐng)求信息,最后通過(guò)回調(diào)方式處理服務(wù)端返回的響應(yīng)信息。這一切都是由JavaScript代碼實(shí)現(xiàn)的。

  本文的例子使用ASP.NET程序?qū)崿F(xiàn),在實(shí)現(xiàn)上要做到以下幾點(diǎn):

  1、AJAX可以在不同的ASP.NET頁(yè)上向不同的服務(wù)端頁(yè)發(fā)送請(qǐng)求。

  2、遠(yuǎn)程頁(yè)面URL可以包含動(dòng)態(tài)可計(jì)算的參數(shù),這樣做可以在ASP.NET的后端代碼中更方便地建立URL字符串。

  3、遠(yuǎn)程頁(yè)在更新HTML頁(yè)之前可以使用復(fù)雜的數(shù)據(jù)進(jìn)行響應(yīng),這也可以由ASP.NET的后端代碼完成。

  4、一個(gè)服務(wù)端頁(yè)面可以是一個(gè)擴(kuò)展的第三方的頁(yè)面,也可以是本身的web頁(yè)或服務(wù)。

  以上的幾點(diǎn)如圖1所示

  

  圖1

  實(shí)現(xiàn)基本的AJAX JavaScript方法

  我將JavaScript方法分成兩部分:調(diào)用特殊頁(yè)的JavaScript方法和一般的JavaScript方法。特殊的方法包括一個(gè)回調(diào)方法,它的作用是更新頁(yè)面內(nèi)容。而其它的AJAX方法負(fù)責(zé)建立一個(gè)XmlHttp對(duì)象,并向服務(wù)端發(fā)出一個(gè)異步的HTTP請(qǐng)求。

  建立的XmlHttp對(duì)象因客戶端瀏覽器的不同而有所差異。本文只考慮兩種瀏覽器:一個(gè)是Microsoft的IE系列瀏覽器;另一個(gè)是 Mozilla系列瀏覽器,包括Mozilla Firefox、Netscape和Safari。我也在Opera瀏覽器上測(cè)試過(guò),但我不能保證本文的代碼可以很好地運(yùn)行Opera瀏覽器上。下面是如何建立XmlHttp對(duì)象的代碼:
  

    function GetXmlHttpObject(handler)

  {

  var objXmlHttp = null;

  if (!window.XMLHttpRequest)

  {

  // Microsoft

  objXmlHttp = GetMSXmlHttp();

  if (objXmlHttp != null)

  {

  objXmlHttp.onreadystatechange = handler;

  }

  }

  else

  {

  // Mozilla | Netscape | Safari

  objXmlHttp = new XMLHttpRequest();

  if (objXmlHttp != null)

  {

  objXmlHttp.onload = handler;

  objXmlHttp.onerror = handler;

  }

  }

  return objXmlHttp;

  }

  function GetMSXmlHttp()

  {

  var xmlHttp = null;

  var clsids = ["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.5.0","Msxml2.XMLHTTP.4.0","Msxml2.XMLHTTP.3.0",

  "Msxml2.XMLHTTP.2.6","Microsoft.XMLHTTP.1.0",

  "Microsoft.XMLHTTP.1","Microsoft.XMLHTTP"];

  for(var i=0; i

  xmlHttp = createXmlHttp(clsids[i]);

  }

  return xmlHttp;

  }

  function createXmlHttp(clsid) {

  var xmlHttp = null;

  try {

  xmlHttp = new ActiveXObject(clsid);

  lastclsid = clsid;

  return xmlHttp;

  }

  catch(e) {}

  }

  由于MSXML5只是為Office設(shè)計(jì)的,因此,我們可以不考慮MSXML5。所以GetMSXmlHttp方法可以簡(jiǎn)化為以下形式:
  
    function GetMSXmlHttp() {

  var xmlHttp = null;

  var clsids = ["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.4.0","Msxml2.XMLHTTP.3.0"];

  for(var i=0; i

  xmlHttp = createXmlHttp(clsids[i]);

  }

  return xmlHttp;

  }

  我們可以看出,GetXmlHttpObject方法有一個(gè)handle參數(shù),這個(gè)參數(shù)指向一個(gè)回調(diào)方法,這個(gè)回調(diào)方法將被定義在每一個(gè)需要刷新的aspx頁(yè)中。現(xiàn)在我們已經(jīng)有了一個(gè)XmlHttp對(duì)象,接下來(lái)我們可以發(fā)送一個(gè)異步的HTTP請(qǐng)求了。
  
    function SendXmlHttpRequest(xmlhttp, url) {

  xmlhttp.open(’GET’, url, true);

  xmlhttp.send(null);

  }
  在以上代碼中我使用了一個(gè)GET HTTP請(qǐng)求發(fā)送了一個(gè)URL,你可以很容易修改以上的JavaScript代碼,使其發(fā)送其它的HTTP方法。

  寫在aspx頁(yè)中的方法

  現(xiàn)在我們已經(jīng)編寫完調(diào)用遠(yuǎn)程頁(yè)面的所有方法。為了執(zhí)行這些方法,我們需要為GetXmlHttpObject方法傳遞一個(gè)回調(diào)方法名,然后向SendXmlHttpRequest方法傳遞一個(gè)URL字符串。下面是相應(yīng)的實(shí)現(xiàn)代碼:
  
    var xmlHttp;

  function executeCall(url)

  {

  try

  {

  xmlHttp = GetXmlHttpObject(CallbackMethod);

  SendXmlHttpRequest(xmlHttp, url);

  }

  catch(e){}

  }

  //CallbackMethod will fire when the state

  //has changed, i.e. data is received back

  function CallbackMethod()

  {

  try

  {

  //readyState of 4 or ’complete’ represents

  //that data has been returned

  if (xmlHttp.readyState == 4 || xmlHttp.readyState == ’complete’)

  {

  var response = xmlHttp.responseText;

  if (response.length > 0)

  {

  //update page

  document.getElementById("elementId").innerHTML = response;

  }

  }

  }

  catch(e){}

  }

  CallbackMethod方法負(fù)責(zé)更新頁(yè)面。在我們的例子中,它只更新了指定的HTTP對(duì)象的inner HTML。但在實(shí)際應(yīng)用中,可以更新更多的內(nèi)容。

  最后要解決的問(wèn)題是我們?nèi)绾卧赼spx頁(yè)中調(diào)用executeCall方法。如何調(diào)用executeCall方法取決于這個(gè)頁(yè)面要做什么。在一些情況下,executeCall方法可以在JavaScript事件出發(fā)時(shí)調(diào)用。如果這樣做,我們還可以使用相應(yīng)的aspx頁(yè)后端C#代碼將這個(gè)方法注冊(cè)為啟動(dòng)腳本。

  Page.RegisterStartupScript("ajaxMethod", String.Format(" ", url));

  我們可以將上面代碼加到ASP.NET后端代碼的Page_Prerender或Page_Load方法中。

  服務(wù)端頁(yè)面

  讓我們看看服務(wù)端頁(yè)面象什么。如果它是一個(gè)ASP.NET頁(yè)(我們假設(shè)的),我們僅僅對(duì)它的后端代碼感性趣。我們可以將.aspx文件中代碼都刪除,這樣絲毫不會(huì)影響這個(gè)aspx頁(yè)的功能。

  例如,我們有一個(gè)將攝氏度轉(zhuǎn)換為華氏度的web service。如果你將這個(gè)web service的URL的引用加入到你的工程中,Visual Studio將產(chǎn)生一個(gè)叫"com.developerdays.ItempConverterservice" 的代理類,這個(gè)代理類使用當(dāng)前的命名空間。有一個(gè)名為getTemp.aspx的aspx頁(yè),它接收一個(gè)叫"temp"的查詢參數(shù),這參數(shù)包含一個(gè)整數(shù)的攝氏度值。如http://localhost/getTemp.aspx?temp=25。這個(gè)aspx頁(yè)的后端代碼如下:
  
    private void Page_Load(object sender, EventArgs e)

  {

  Response.Clear();

  string temp = Request.QueryString["temp"];

  if (temp != null)

  {

  try

  {

  int tempC = int.Parse(temp);

  string tempF = getTempF(tempC);

  Response.Write(tempF);

  }

  catch

  {}

  }

  Response.End();

  }

  private string getTempF(int tempC)

  {

  com.developerdays.ITempConverterservice

  svc = new ITempConverterservice();

  int tempF = svc.CtoF(tempC);

  return tempF.ToString();

  }

  現(xiàn)在我們要建立一個(gè)可以調(diào)用上面的getTemp.aspx頁(yè)的請(qǐng)求字符串,這個(gè)字符串將傳遞到RegisterStartupScript方法中。代碼如下:
  
    int tempC = 25;

  string url = String.Format("http://localhost/" +

  "getTemp.aspx?temp={0}", tempC);

  在一些簡(jiǎn)單情況,如果要傳遞的只是簡(jiǎn)單的文本,可以通過(guò)URL直接傳給executeCall方法。

  結(jié)論

  本文舉了一個(gè)在任何ASP.NET程序都可以使用AJAX技術(shù)的簡(jiǎn)單例子。AJAX除了能給用戶一些全新的體驗(yàn)外,也有一些缺點(diǎn)和不足。至于是否使用AJAX技術(shù),這完全取決于開發(fā)人員自身,在本文中我只是舉了個(gè)簡(jiǎn)單的例子,學(xué)習(xí)它并不需要太多的時(shí)間,也不需要任何特殊的技能。

關(guān)鍵詞:ASP.NETAJAX