探讨微软ASP.NET AJAX控件开发技术(服务器端)
一、簡(jiǎn)介
到目前為止,我們已經(jīng)討論了開發(fā)Ajax控件所涉及的客戶端相關(guān)技術(shù)?,F(xiàn)在,讓我們來討論此過程中與服務(wù)器端相關(guān)的一些技術(shù)。
需要說明的是,在【客戶端】篇中我們的舉例本質(zhì)上僅是使用ASP.NET AJAX框架提供的面向?qū)ο驤avaScript技術(shù)來增強(qiáng)了一個(gè)客戶端圖像組件,而沒有明顯涉及到AJAX技術(shù)(除了ScriptManager在后臺(tái)以AJAX方式下載并管理客戶端腳本代碼外)。所以,這個(gè)例子是簡(jiǎn)單的,僅憑客戶端相關(guān)知識(shí)就可以使用這個(gè)增強(qiáng)控件。
但是,在實(shí)際開發(fā)中,當(dāng)要增強(qiáng)的客戶端控件涉及到AJAX技術(shù)時(shí),或者干脆是想增強(qiáng)服務(wù)器端組件(如UpdatePanel控件)時(shí),我們必須進(jìn)行相關(guān)的服務(wù)器端編程,而這要求我們必須對(duì)Ajax控件開發(fā)中所涉及的服務(wù)器端相關(guān)聯(lián)的類有所了解。而且,還要以ASP.NET 2.0服務(wù)器控件開發(fā)相關(guān)知識(shí)為基本前提,特別是在開發(fā)復(fù)雜的Ajax控件時(shí)。
在本篇中,我們要重新構(gòu)造一個(gè)增強(qiáng)的圖像按鈕控件MySrvImageButton,此控件將以ASP.NET 2.0服務(wù)器控件ImageButton為基礎(chǔ)。
二、AJAX控件開發(fā)服務(wù)器端相關(guān)技術(shù)
首先,讓我們來看一下AJAX控件開發(fā)服務(wù)器端相關(guān)組件及其關(guān)系,這些類之間的繼承關(guān)系圖如下圖1所示。
| 圖1:控件開發(fā)涉及的主要服務(wù)器端類之間層次結(jié)構(gòu)圖 |
上圖展示了組件、控件和擴(kuò)展器之間的繼承關(guān)系。如你所見,為了開發(fā)一個(gè)控件(注意,Component和Extender不在本文討論范圍之內(nèi)),我們有兩個(gè)選擇:其一,創(chuàng)建一個(gè)派生自ScriptControl的類;其二,創(chuàng)建一個(gè)實(shí)現(xiàn)IScriptControl接口的類。但是,如果你想使你的控件從WebControl派生,那么,ScriptControl應(yīng)該是一個(gè)更好的選擇—因?yàn)樗桥缮訵ebControl控件本身。但是,如果你想從頭開發(fā)創(chuàng)建你的控件,并且不要求實(shí)現(xiàn)WebControl所具備的任何內(nèi)在特征,那么,實(shí)現(xiàn)IScriptControl則更為恰當(dāng)。此外,當(dāng)你想在一個(gè)現(xiàn)有控件(例如本文中的MySrvImageButton)中添加Ajax特征時(shí)選擇使用接口IScriptControl也會(huì)是你的選擇。但是這兩種方法都要求重載下列兩個(gè)方法:①、GetScriptDescriptors;②、GetScriptReferences。
三、GetScriptDescriptors
這個(gè)方法負(fù)責(zé)在客戶端以自動(dòng)方式生成$create語句(而在上篇中是使用手工方式)。它使用了一個(gè)特殊類ScriptDescriptor來生成它。在繼續(xù)往下討論前,首先讓我們來瀏覽一下ScriptDescriptor類中的繼承層次圖(如圖2所示):
| 圖2:ScriptDescriptor類中的繼承層次圖 |
顯然,每一種具體類型的組件都存在其單獨(dú)的描述符。如果你在開發(fā)一個(gè)常規(guī)組件,那么,這個(gè)方法會(huì)返回一個(gè)ScriptComponentDescriptor的實(shí)例。對(duì)于擴(kuò)展器而言,該方法返回的是一個(gè)ScriptBehaviorDescriptor實(shí)例;而對(duì)于一個(gè)控件,則返回ScriptControlDescriptor類的實(shí)例。該描述符中提供了一些特定的方法用于創(chuàng)建服務(wù)器端與客戶端的“連接”。下面,還是讓我們來分析一個(gè)有關(guān)$Create語句是如何在服務(wù)器端“注入”的簡(jiǎn)短示例:
//上篇中從客戶端以手工方式使用$create {'hoverImageUrl':'Images/updateh.gif'}, {'click':buttonClicked}, null, $get('cliBtn')); new ScriptControlDescriptor("AjaxImageButtonLib.MySrvImageButton", |
在上面的代碼中,我們?cè)跇?gòu)造器中傳遞客戶端類型(盡管客戶端和服務(wù)器端具有相同的類型名)和DOM元素ID。這一步將填充$Create語句的第一個(gè)和最后一個(gè)參數(shù)。此后,我們?cè)O(shè)置hoverImageUrl屬性,它對(duì)應(yīng)于$Create語句的屬性部分。最后,通過設(shè)置Click事件處理器,我們填充$Create語句的事件部分。下面是腳本描述符中暴露的幾個(gè)重要的方法:
1)AddProperty()
這個(gè)方法能夠在客戶端添加一個(gè)屬性。第一個(gè)參數(shù)相應(yīng)于屬性名,第二個(gè)參數(shù)對(duì)應(yīng)該參數(shù)的取值。
2)AddEvent()
這個(gè)方法在客戶端添加一個(gè)事件。第一個(gè)參數(shù)相應(yīng)于事件名,第二個(gè)參數(shù)對(duì)應(yīng)你想綁定的函數(shù)的名稱。
3)AddScriptProperty()
這個(gè)方法能夠把JavaScript代碼指定為屬性的一個(gè)值。對(duì)于復(fù)雜的屬性賦值通常都要求這樣的操作。
4)AddElementProperty()
這個(gè)方法在客戶端添加一個(gè)屬性,但是其與AddProperty方法間的區(qū)別在于,該值作為一個(gè)參數(shù)傳遞給$get方法。
5)AddComponentProperty()
這個(gè)方法負(fù)責(zé)在$Create語句的Component部分添加一個(gè)組件引用。該值將被用于$find語句中實(shí)現(xiàn)屬性的賦值。這個(gè)方法的第一個(gè)參數(shù)相應(yīng)于屬性名,第二個(gè)參數(shù)對(duì)應(yīng)該組件的id。
四、GetScriptReferences
這個(gè)方法負(fù)責(zé)在ScriptManager中注冊(cè)JavaScript文件。在這個(gè)方法中,針對(duì)每一個(gè)要求的JavaScript文件,我們都需要?jiǎng)?chuàng)建一個(gè)相應(yīng)的ScriptReference實(shí)例。例如,在圖像按鈕例子中,我們按如下方式注冊(cè)JavaScript文件:
| IEnumerable<ScriptReference> IScriptControl.GetScriptReferences() { return new ScriptReference(Page.ResolveUrl("~/SrvImageButton.js")); } |
此外,我們還可以以嵌入式資源方式注冊(cè)JavaScript文件。為此,我們必須首先在Visual Studio的解決方案資源管理器中把一個(gè)JavaScript文件標(biāo)記為一種嵌入式資源。然后,我們必須添加上WebResource屬性以便利用Asp.Net 2.0 Web資源處理器。下列代碼展示了如何把一個(gè)JavaScript文件注冊(cè)為一個(gè)嵌入式資源:
[assembly: WebResource("MyControls.SubControl.Script1.js", "text/javascript")] |
此外,如果我們想實(shí)現(xiàn)IScriptControl接口而不是從ScriptControl中繼承的話,我們還必須重載OnPreRender與Render方法。這樣將能確保ScriptManger識(shí)別出該服務(wù)器控件是一個(gè)支持Ajax功能的控件。
下列代碼展示了開發(fā)基于ASP.NET 2.0服務(wù)器端控件的AJAX控件時(shí)必須在服務(wù)器端實(shí)現(xiàn)的最少代碼:
using System; |
上面代碼中,我們?cè)贠nPreRender方法中實(shí)現(xiàn)注冊(cè)控件,而在Render方法中注冊(cè)腳本描述符部分。當(dāng)然,如果頁面上不存在ScriptManager控件的話,我們必須拋出一個(gè)錯(cuò)誤提示。但是,如果你正在開發(fā)非基于ASP.NETAJAX框架的控件的話,你完全可以從頁面中刪除ScriptManager控件。
五、創(chuàng)建基于ASP.NET服務(wù)器端控件的增強(qiáng)AJAX圖像控件
(一)創(chuàng)建示例AJAX網(wǎng)站
啟動(dòng)Visual Studio 2005,選擇“文件→新建網(wǎng)站…”,然后選擇“ASP.NET AJAX-Enabled Web Site”模板,命名工程為“AjaxServCtrlTest”,并選擇C#作為內(nèi)置支持語言,最后點(diǎn)擊“確定”。
(二)創(chuàng)建AJAX技術(shù)支持的增強(qiáng)服務(wù)器控件
點(diǎn)擊菜單“文件→添加→新建項(xiàng)目…”,在“添加新項(xiàng)目”對(duì)話框中,從左邊選擇“項(xiàng)目類型”為“Visual C#→Windows”,從右邊選擇“模板類型”為“Web控件庫”,輸入控件庫的名字為AjaxImageButtonLib,選擇目標(biāo)目錄為前面創(chuàng)建的網(wǎng)站根目錄,最后點(diǎn)擊“確定”。
接下來,根據(jù)我們前面的分析,把類庫源WebCustomControl1.cs文件的內(nèi)容更改為以下形式:
//…………(省略命名空間引用部分) System.Web.UI.WebControls.ImageButton, IScriptControl return (value == null) ? string.Empty : (string)value; ("ScriptManager required on the page."); new ScriptControlDescriptor("AjaxImageButtonLib.MySrvImageButton", ClientID); |
首先,我們注意到我們要?jiǎng)?chuàng)建的新控件MySrvImageButton繼承自ASP.NET服務(wù)器控件ImageButton,并繼承了接口IScriptControl。
有了前面的理論描述,在此,我們省略對(duì)于其中幾個(gè)常規(guī)方法的描述。
接下來,我們要構(gòu)建這個(gè)控件庫(即程序集)。右擊此庫工程,并點(diǎn)擊“生成”命令以生成程序集AjaxImageButtonLib.dll,此庫文件中即包含了我們的服務(wù)器控件。
(三)創(chuàng)建客戶端JavaScript代碼
這里創(chuàng)建的客戶端控件類相應(yīng)的JavaScript文件ImageButton.js在內(nèi)容上完全相同,只不過為了區(qū)別起見,我們進(jìn)行了某些地方的重新命名罷了。在此不再贅述。
(四)在示例網(wǎng)頁中應(yīng)用構(gòu)建的新控件
以鼠標(biāo)右擊前面網(wǎng)站AjaxServCtrlTest,把它設(shè)置為“啟動(dòng)項(xiàng)目”。事實(shí)上,因?yàn)檫@個(gè)網(wǎng)站工程與前面的類庫工程創(chuàng)建于同一個(gè)方案下,所以,在前面生成程序集AjaxImageButtonLib.dll的一結(jié)束,新建的服務(wù)器控件就被自動(dòng)添加到Visual Studio 2005工具欄中,如下圖3所示。于是,我們可以直接把這個(gè)控件拖動(dòng)到示例網(wǎng)頁Default.aspx中。
| 圖3:拖動(dòng)新建的服務(wù)器控件到示例網(wǎng)頁中 |
根據(jù)前面的控件代碼實(shí)現(xiàn),不出所料,點(diǎn)擊上圖3中的圖形按鈕控件,即可在其相應(yīng)的“屬性”對(duì)話框中設(shè)置這個(gè)控件的hoverImageUrl屬性,而且指定其ClientClickFunction方法(其實(shí)正是此控件的click事件處理器函數(shù)指針)。
注意,因?yàn)榭丶a中的方法GetScriptReferences已經(jīng)為我們自動(dòng)生成了前面提到的$create方法,所以我們不需要再在ScriptManager中注冊(cè)在本篇中創(chuàng)建的JavaScript文件—SrvImageButton.js了。
(五)運(yùn)行及性能簡(jiǎn)析
現(xiàn)在,請(qǐng)按F5鍵運(yùn)行此頁面并移動(dòng)鼠標(biāo)到圖像按鈕上觀察,你會(huì)注意到結(jié)果與上篇中的效果一致(即在鼠標(biāo)移動(dòng)切換新圖像時(shí),這些動(dòng)作都發(fā)生于客戶瀏覽器端而不再與服務(wù)器端相關(guān))。下圖4相應(yīng)于此示例頁面運(yùn)行時(shí)刻快照。
| 圖4:示例網(wǎng)頁運(yùn)行時(shí)刻屏幕快照 |
通過以鼠標(biāo)右擊網(wǎng)頁并選擇彈出菜單中的“查看源文件”觀察上、下篇中示例頁面相應(yīng)的源碼,我們會(huì)注意到其內(nèi)容基本是一致的。另外,通過使用Fiddler觀察這兩個(gè)示例頁面下載到客戶端時(shí)各模塊的大小,你也會(huì)注意到基本一致,如下面圖5所示。
| 圖5:兩個(gè)示例頁面下載到客戶端時(shí)各模塊大小比較 |
因?yàn)楸疚膬蓚€(gè)例子極為簡(jiǎn)單,所以其性能基本平衡。但隨著服務(wù)端編程的復(fù)雜化,本篇中基于服務(wù)器端控件的擴(kuò)展方案應(yīng)該有較大的性能損耗。但應(yīng)該仍具有令人滿意的效果,這也正是AJAX Control Toolkit控件數(shù)量急劇增加的重要原因之一。而上篇中的方案基于“純粹”(相對(duì)而言)的客戶端,即使性能上與本篇中方案相差無幾,但是卻明顯多出了跨越服務(wù)器端平臺(tái)的優(yōu)勢(shì),這也正是上篇中方案吸引人的主要原因。
六、總結(jié)
雖然以上、下兩個(gè)篇幅形成此文,但是這也僅能通過簡(jiǎn)短的例子向你闡述了開發(fā)ASP.NETAJAX框架中的Ajax控件所涉及的主要技術(shù)。盡管目前的ASP.NET AJAX框架已經(jīng)形成正規(guī)的1.0版本,而且這個(gè)框架為基于AJAX技術(shù)開發(fā)以ASP.NET 2.0為主的Web應(yīng)用提供了全方位支持,但是這個(gè)框架仍然在許多方面有待改進(jìn)。事實(shí)上,我們可以進(jìn)一步沿著ASP.NET AJAX客戶端與服務(wù)器端架構(gòu)層次關(guān)系圖進(jìn)一步擴(kuò)展其底層。當(dāng)然,在此框架與Visual Studio整合方面也存在相當(dāng)?shù)耐诰驖摿Α?/p>
如今,隨著微軟Silverlight技術(shù)的推出,ASP.NET AJAX框架的重要性日顯突出。自然,與此框架相關(guān)的控件開發(fā)也必將在這一大環(huán)境中占居著重要的位置。
轉(zhuǎn)載于:https://www.cnblogs.com/xujiaci/archive/2007/09/13/891417.html
總結(jié)
以上是生活随笔為你收集整理的探讨微软ASP.NET AJAX控件开发技术(服务器端)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 假如没有手机
- 下一篇: 深入剖析微软ASP.NET Ajax中的