ASP.NET Ajax 學習(一)伺服器端部分

來源:互聯網
上載者:User

ASP.NET Ajax架構提供了兩種開發模型:伺服器端編程和用戶端編程。前者使用方便,開發人員可以不懂JS和Ajax,而是通過傳統的ASP.NET開發方式完成Ajax應用的開發,但是其控制粒度較粗,他比較適用於在已有系統上實現局部的非同步重新整理功能。而後者開發難度相對較大,需要開發人員熟悉JavaScript,並熟悉ASP.NET AJAX提供的各種文法支援及用戶端編程模型,但是其控制粒度精細,有利於提高應用的效能和品質。

         我們可以不基於任何Ajax架構開發出Ajax程式,Ajax的核心是XmlHttpRequest對象,但是這種不基於架構開發Ajax程式非常麻煩,需要自己根據不同的瀏覽器對象建立不同的XmlHttpRequest對象,然後自己定義回呼函數,在回呼函數中實現邏輯,發送非同步請求等。

         MS基於上述的複雜的工作,實現了一個Ajax架構,即使ASP.Net Ajax架構,該架構與VS2008開發環境已經整合了,而在VS2005中還需要安裝一個ASPAJAXExtSetup.msi, 並且進行Web.Config的配置,才可以實現ASP.Net Ajax架構,在有了ASP.net Ajax架構以後,我們就可以在JavaScript中通過WebService調用背景.CS檔案代碼了。

第一部分 服務端部分 

一.Asp.net Ajax 基礎知識 

Microsoft ASP.Net Ajax的安裝包包括以下幾部分:

一.ASP.NET 2.0 AJAX Extensions          asp.net ajax的核心部分,包括最重要和最基本的一些控制項、組件和功能,例如伺服器端的ScriptManager控制項、UpdatePanel控制項,用戶端的JavaScript物件導向方面擴充、調試類、Web Service代理等。

二.ASP.NET AJAX Futures CTP      asp.net ajax的非核心部分,其中包括伺服器端的擴充器控制項(Extender Control)、Web組件,用戶端的各種控制項、拖放功能實現、ASP.NET AJAX XML指令碼等,用戶端組件有動畫組件,行為組件,驗證器組件等;用戶端控制項有ListView,Hyperlink,selector,Button,Label等空間。伺服器端的樣式擴充器控制項有DragoverlayExtender等。。

三.Microsoft AJAX Library     包含了ASP.NET AJAX的用戶端JavaScript檔案,它裡麵包括的js檔案就是Extensions.dll和preview.dll中包括的js檔案的集合,當你不用asp.net ajax架構時,可以使用該安裝檔案,否則我們無需安裝,只要安裝了Extensions.dll和preview.dll就包括了該安裝包中的所有的用戶端指令碼了。

四.ASP.NET AJAX Control Toolkit          包含了數十種基於ASP.NET AJAX的、組件化的、提供某個專一Ajax功能的ASP.NET AJAX伺服器端控制項和ASP.NET AJAX擴充器控制項

 

Extensions.dll中包括的Microsoft AJAX Library部分的用戶端js檔案有

MicrosoftAjax.js:該檔案包含了ASP.NET AJAX的核心內容與功能,例如對JavaScript物件導向方面的擴充,Error、Type、StringBuilder等各種用戶端類型,對調用Web Service即XMLHttpRequest對象的封裝)的支援等。在此基礎上,也擴充了包括最基礎的用戶端組件/控制項、用於非同步呼叫的XMLHttpExecutor、WebRequest對象、用於訪問ASP.NET 2.0應用服務的ProfileService和AuthenticationService對象等ASP.NET AJAX的完整特性。該檔案同樣負責抹平不同瀏覽器之間JavaScript以及DOM訪問的細微差別,以期提供給開發人員經過封裝的、統一的、標準的API。一般來講,這些都是一個完善的ASP.NETAJAX應用程式所必需的功能,所以在預設條件下,ScriptManager將把這個檔案作為ASP.NET AJAX的核心指令檔發送至用戶端。

 

MicrosoftAjaxTimer.js:該檔案中定義了用戶端的Timer組件,用來配合ASP.NET AJAX服

務器端Timer組件實現,提供定時觸發事件(用戶端以及伺服器端)的功能。

 

MicrosoftAjaxWebForms.js:該檔案中定義了一個非常重要的用戶端對象:PageRequestManager。PageRequestManager旨在在用戶端為開發人員提供ASP.NET伺服器端頁面生存周期一樣的開發模型,以物件導向的方式控制、維護用戶端非同步回送的全過程。如果ScriptManager中啟用了局部更新、非同步回送的支援(EnablePartialRendering屬性設定為true),則該檔案將被自動發送至用戶端。該指令碼時服務端控制項UpdatePanel得以正常工作的基礎。

 

Preview.dll中包括的Microsoft AJAX Library部分的用戶端js檔案有:

PreviewScript.js:該檔案包含了ASP.NET AJAX中全部的用戶端組件/控制項的實現,包括表示簡單介面元素的TextBox、表示複雜繫結資料行表的ListView、驗證使用者輸入的Validator、為HTML元素提供某些附加行為的Behavior、位於用戶端的離線資料來源DataSource、響應使用者操作的Action等,以及對ASP.NET AJAX XML指令碼的支援。同樣,該檔案還聲明了這部分內容在不同瀏覽器之間相容的代碼。

 

PreviewDragDrop.js:該檔案用於提供ASP.NET AJAX中滑鼠拖動功能的實現。

PreviewWebParts.js與WhidbeyWebParts.js:該檔案定義了和ASP.NET Web組件(WebPart)

協同工作的相關指令碼。

PreviewGlitz.js:該檔案用於實現某些介面中的特效,例如淡入淡出、動畫效果等。

 

二.ScriptManager引用指令碼 

ASP.NET AJAX的程式集System.Web.Extensions.dll 和Microsoft.Web.Preview.dll 中包含了

Debug和Release兩個版本的用戶端指令碼拷貝,ScriptManager將選擇使用嵌入到該程式集中的這部分資源來產生用戶端必需的指令碼。用戶端架構指令碼將不會用直接引用的方式發送至用戶端.

預設情況,ScriptManager會自動將MicrosoftAjax.js檔案和MicrosoftAjaxWebForms.js檔案發送至用戶端。若頁面中還需要更加完善的由其他ASP.NET AJAX用戶端指令碼提供的功能,或者一些自訂的指令檔,則需要手工在ScriptManager中添加對這些檔案的引用,如需要使用ASP.NET AJAX Futures CTP部分組件的功能.則需要使用<asp:ScriptReference Assembly="Microsoft.Web.Preview" />方式來引用prviewScript.js指令檔

 

ScriptManager的EnablePartialRendering屬性設定為true,這樣ASP.NET AJAX會在頁面中添加一些額外的JavaScript指令碼來截獲實現ASP.NET回送的__doPostBack()函數,並接下來使用XMLHttpRequest對象替代傳統的整頁回送,向伺服器發出非同步請求

 

三.用戶端調用頁面的方法 

要將ScriptManager的EnablePageMethods屬性設定為true,然後定義在伺服器端的一個靜態方法(注意方法一定要為靜態,且必須添加[System.Web.Services.WebMethod]屬性):

 

[System.Web.Services.WebMethod]

public static string SayHello(string name)

{

return string.Format("hello, {0}!", name);

}

 

 

隨後即可在用戶端JavaScript中用下面這行語句直接調用該方法(注意該方法定義在PageMethods中):

PageMethods.SayHello("Dflying", cb_sayHello);

其中cb_sayHello表示該非同步呼叫完成後將要觸發的回呼函數。

 

四.引入程式集中內嵌的指令碼資源:

 

<asp:ScriptManager runat="server">

<Scripts>

<asp:ScriptReference Assembly="Microsoft.Web.Preview" />

</Scripts>

</asp:ScriptManager>

 

 

ASP.NET AJAX的Value-add部分的指令碼均要通過這種方式添加到頁面中

 

五.引入單獨的指令檔:

 

<asp:ScriptManager runat="server">

<Scripts>

<asp:ScriptReference Path="MyPath/MyCustomScript.js" />

</Scripts>

</asp:ScriptManager>

 

 

<Scripts>標籤下可以定義多個<asp:ScriptReference>,分別代表不同的指令碼。

 

六.同一個scriptManager引入不同的Debug版本和Release版本檔案 

ScriptManager控制項在設計時自然考慮到了這個需求,它提供了一個名為ScriptMode的枚舉型屬性,用以表示scriptmanager每次向用戶端發送的是debug版本還是release版本的js指令檔然而某些情況下,我們可能希望某個指令碼不使用整個ScriptManager中的全域設定。例如,ScriptManager中指定了使用Release版本的指令碼,但我們卻希望其中的某一個指令碼應用Debug版本來方便調試,這時,我們可以使用<asp:ScriptReference>標籤(注意:不是<asp:ScriptManager>標籤)中的同名屬性——ScriptMode,來覆蓋定義在ScriptManager中的設定,其預設值為Inherit,表示繼承ScriptManager中的全域設定。需要特別注意的是,若網站部署環境的Machine.config檔案中<deployment>元素的retail屬性設定為true,那麼無論<asp:ScriptManager>和<asp:ScriptReference>中的ScriptMode屬性如何設定,ScriptManager都將直接發送Release版本的指令碼。

 

ScriptManager將在解析每一個指令碼時觸發ResolveScriptReference事件,在伺服器端ScriptManager1_ResolveScriptReference() 函數中, 我們可以通過e.Script參數得到目前待解析的這個ScriptReference對象

 

ScriptManager控制項的LoadScriptsBeforeUI布爾值屬性可用來設定ASP.NET AJAX指令檔在最終HTML頁面中出現的位置,其預設值為true,表示指令檔的引用(即<script>標籤)將出現在所有介面HTML元素之前,這樣即可保證頁面顯示時已經載入並初始化了ASP.NET AJAX的用戶端架構,使用者又可以立即開始使用該程式

 

七.ScriptManager引入指令碼支援本地化功能 

若要使用ScriptManager內建的本地化功能,我們需要注意以下幾點:

(1) 必須設定ScriptManager的EnableScriptLocalization屬性為true。

(2) 必須使用ScriptPath直接引入指令碼,而不能使用Assembly和Name屬性引入內嵌在程式集中的指令碼。

(3) 確保ResourceUICultures屬性指定的各個地區都有與之相配的指令檔。例如在上面的例子中,ResourceUICultures屬性設定為了zh-CN和en-US,那麼我們就要保證網站給出了Scripts/MyControl.zh-CN.js和Scripts/MyControl.en-US.js這兩個指令碼。

 

八.通知指令碼資源載入完成

在ASP.NET AJAX頁面中,每一個將要與用戶端架構協同啟動並執行指令檔的末尾都必須包含如下一行代碼,用來發出這個通知:if(typeof(Sys) !== "undefined")Sys.Application.notifyScriptLoaded();因此,我們在編寫自訂的指令檔時,也要在末尾添加上面這一行。該指令檔嵌入到某個程式集中,並通過<asp:ScriptReference>的Assembly和Name屬性引入,那麼ASP.NET AJAX將自動在檔案末尾添加上述這一行通知指令碼資源載入完成的聲明。若指令檔本身已經有了這一行,將導致這行代碼被執行兩次,進而引發異常。為瞭解決這個問題,<asp:ScriptReference>特意引入了NotifyScriptLoaded這個布爾值屬性。其預設值為true,即自動為嵌入到程式集中的指令碼添加通知指令碼資源載入完成的聲明。

 

九.管理webservice用戶端代理: 

<asp:ServiceReference>標籤提供了一個布爾值的屬性:InlineScript,其預設值為

false。若將其設定為true,則該Web Service的用戶端代理將不再通過“Web Service檔案路徑+/js(或jsdebug)尾碼”的形式單獨取得,而是嵌入到頁面HTML代碼中,並隨之一同發送至用戶端,也就是所謂的“inline(內聯)”。一般來講,由於Web Service用戶端代理檔案都比較小,真正用來傳輸檔案的時間並不多,所以傳輸這個檔案所必須的準備工作——建立和關閉一次請求這個代理檔案的HTTP串連——所花費的時間,在整個HTTP請求所花費的時間中也就相對地佔有較大的比例。而若像這樣將其內聯到頁面中,即可避免這一次額外的HTTP請求,進而也就略微地提高了頁面載入的效能。

 

十.異常處理: 

ScriptManager控制項的一個非常重要的屬性:AllowCustomErrorsRedirect,該屬性為布爾類型,預設值為true,表示在非同步更新發生異常時是否沿用Web.config<customErrors>節中的設定。Web.config的<customErrors>節中可以指定應用程式層級的錯誤處理頁面,這將通過重新導向至某個專門顯示異常的頁面來實現。而對於Ajax程式而言,頁面跳轉則是應該竭力避免的,因此一般來講,最好將其設定為false。

ScriptManager的AsyncPostBackError事件將在非同步回送引發異常時觸發,AsyncPostBackErrorMessage屬性工作表示了非同步回送過程中發生的異常將顯示出的訊息

 

十一.以編程方式控制ScriptManager 

ScriptManager提供一個名為RegisterAsyncPostBackControl()的方法,該方法接受一個類型為Control的參數,使用該方法,ScriptManager的EnablePartialRendering屬性值一定要設定成true。

UpdatePanel中包圍的內容以及其指定的作為觸發器的控制項均自動在ScriptManager中註冊為採用非同步方式進行回送,而無需我們手工幹預。修改ScriptManager的EnablePartialRendering、EnableScriptGlobalization、EnablePageMethods和EnableScriptLocalization等屬性需要注意的是,修改這些屬性值最好在Page的PreInit事件處理函數中進行。若晚於該階段,ScriptManager將可能會拋出異常。

 

ScriptManager還提供了一個唯讀布爾型屬性:IsInAsyncPostBack。類似用傳統ASP.NET模型中的Page.IsPostBack屬性判斷當前伺服器執行的代碼是否由回送引發,IsInAsyncPostBack可以用來判斷當前伺服器執行的代碼是否是由非同步回送所引發的。

 

代碼

protected void Page_Load(object sender, EventArgs e)

{

ScriptManager theScriptManager = ScriptManager.GetCurrent(this);

if (theScriptManager.IsInAsyncPostBack)

{

// 僅在非同步回送中執行的代碼。

}

}

 

 

ScriptManager的布爾型屬性SupportsPartialRendering,用來判斷當前的瀏覽器是否支援Ajax的局部更新功能;ScriptManager的布爾型屬性IsDebuggingEnabled,用來判斷當前的請求是否運行於Debug模式;ScriptManager提供的Scripts和Services兩個屬性將分別返回當前ScriptManager對象中引用的指令檔和Web Service的集合;ScriptManager的作用遠不止這些,它還提供了大量的用於註冊頁面中其他ASP.NET AJAX控制項、指令碼塊以及資料的方法,均以“Register”開頭。

 

當在模板頁中使用scriptManager控制項後,在具體的應用了模板頁的頁面中還需要引用其他指令碼時,可以在該頁面中使用scriptManagerProxy控制項,該控制項也可以引入指令檔和webservice,和scriptmanager控制項沒什麼區別。

十二. Updatepanel介紹

updatePanel的實現原理:首先scriptManager和updatePanel在伺服器端達成一致,截獲page的Render()方法並在頁面上為需要進行非同步回送的控制項輸出了一些專門得用於局部重新整理的js腳步,然後在用戶端,若這些控制項通過_doPostBack()函數試圖引發整頁的回送,則上面提到的js腳步將截獲這個調用,並將頁面中各個使用者輸入控制項的值,加上當前的檢視狀態(ViewState)用xmlhttpRequest對象發送回伺服器。而此時伺服器卻對此絲毫不知,仍把它當做一次傳統的回送,老實地引發一次頁面的完整生存周期,並根據回送產生新的頁面結構,隨後又是page的Render()方法中,scriptmanager和updatePanel再一次截獲了其中的實現過程,把不在UpdatePanel中的內容統統剔除,只發送給用戶端真正更新了的部分。最後,用戶端的xmlHttpRequest對象收到了這部分資訊,並在不知不覺中悄悄地更新了UpdatePanel中定義的內容。

 

在用戶端,updatePanel預設呈現為一對div元素。updatePanel的renderMode屬性如果設定成inline,則在用戶端,updatePanel 呈現為span元素。updatePanel還有個唯讀屬性:IsInPartialRendering,因為是唯讀,只會在服務端代碼才用到,它只有在此次回送為非同步回送,且updatePanel中的內容將被更新時才為true;

 

updatePanel可以調用其update()強制它重新整理。

updatePanel的childrenAsTriggers屬性設定為false,則該updatePanel的updateMode屬性必須為Conditional。如果為always,則程式將在運行時拋出異常。

 

注意:非同步回送的過程中整個頁面的所有表單域(包括viewState)都將被完整發送回伺服器。因此,在伺服器端Render步驟之前,非同步回送實際上合傳統的整頁回送沒有任何區別,伺服器端將仍舊進行Init,Load,事件處理等步驟,並可以訪問到頁面中任何控制項的任何屬性,無論其是否在某個updatePanel中,當然,非同步回送過程中伺服器端同樣也可以設定updatePanel之外的某個控制項的屬性,只是render步驟中這個變化並不會被發送回用戶端,所以用戶端也不能看到這個修改。

 

asp.net ajax中還在用戶端為非同步回送的過程添加了若干個事件,包括initialize_Request,beginRequest,pageLoading,pageLoaded和endrequest等,讓用戶端也擁有了類似服務端的生命週期概念。這是配合用戶端的PageRequestmanager對象來實現的。

 

動態載入含有updatePanel的使用者控制項時,要在Page_Init事件中進行,不可以在PageLoad中進行,因為scriptmanager和updatepanel是在pageLoad事件中進行協調和溝通,以便給用戶端發送用於支援局部更新的js腳步。

動態載入控制項可以如下:

 

page.LoadControl("aaa.ascx");

page.controls.Add("aaa.ascx");

 

在下一篇,將介紹ASP.NET Ajax的用戶端部分。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.