傳統型ASP.NET Web Forms是基於同時包含了表現層和後台代碼的Web頁面,所以,緊隨其後出現的ASP.NET AJAX,特別是這個架構的伺服器端控制項並沒有像它們本應該的那樣光芒四射。於是,很多跟隨AJAX時髦的ASP.NET開發人員只是向ASP.NET頁面 中隨意地放置一些UpdatePanel控制項以便使其程式實現基本的AJAX支援。實際上,這隻是防止了頁面的“閃爍”,而根本上頁面還是進行了完整的回 發,並且要經曆整個頁面的生存周期。為了消除ASP.NET Web Forms所依賴的頁面回寄和ViewState等複雜技術,微軟又推出了ASP.NET應用開發的另一個可選架構—ASP.NET MVC。也正是基於前面的分析,ASP.NET MVC中也加入了部分AJAX支援技術。但是,目前的ASP.NET MVC架構尚未發布其正式發行版本,在許多方面仍存在不完善的地方,尤其是對於AJAX技術僅提供了有限的支援。本文中,我們將通過一個簡單的例子來討論 如何藉助於ASP.NET MVC Preview 4架構提供的Ajax.Form方法實現基本的AJAX編程支援。
一、 引言
如果你詳細研究一下ASP.NET MVC架構每個版本之間的變化資訊有關資源,那麼你會注意到新版本的架構中提供了一組新對象,例如AjaxHelper和AjaxExtensions。 藉助於這些對象,你可以為你的ASP.NET MVC應用程式添加流行的Ajax支援功能。此外,藉助於用戶端JavaScript指令碼架構JQuery你也能實現同樣的目的,而且藉助於開源工程 MVCContrib似乎你也能夠實現同樣的Ajax支援。
本文中,我們針對ASP.NET MVC Preview 4架構提供的Ajax作一簡單的討論,分析其提供的基本的Ajax支援功能。
二、 執行個體剖析
(一)建立樣本ASP.NET MVC工程
啟動Visual Studio 2008(我使用的是Team System版本)建立一個新的ASP.NET MVC工程,並命名為MvcBuiltinAjax(註:本執行個體中使用的是目前最新的ASP.NET MVC Preview 4;而且在本例中我們並不關心是否加入單元測試支援架構的問題)。
(二)修改視圖頁面Index.aspx
請注意,本例中我們直接修改視圖頁面Index.aspx。我們將在此頁面中添加一個文字框和一個按鈕控制項。我們的目的是,當點擊此按鈕控制項 時,執行表單提交功能。通過此過程,我們將回調伺服器端並取得相應的字串,而且此字元內容將被以Ajax方式填入到按鈕控制項旁邊的div元素中。圖1展 示了執行個體程式的某一運行時刻的快照。圖中,當我們在文字框中輸入字串“張三”時,後台控制器Action方法查詢已有資料串,如果其中沒有剛剛輸入的內 容,則顯示“ 可以使用這個名字!”;否則,顯示 “此名字已經被使用了!”的提示。
現在,我們來看一下修改視圖Index.aspx中涉及的主要內容,如下所示:
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<p>
<%using (Ajax.Form("ExamineTextBox", new AjaxOptions {UpdateTargetId = "resultDiv" }))
{ %>
<%= Html.TextBox("textBox1")%>
<input type="submit" value="Button"/>
<span id="resultDiv"/>
<% } %>
</p>
</asp:Content>
請注意這裡所使用的Ajax.Form協助函數和引用span元素的UpdateTargetID屬性的值。有關AjaxOptions的用法也有許多值得考察的地方,後面再進行討論。
如果你進一步分析一下運行時刻上面視圖頁面的相應源碼,那麼,你會注意到對應於上面內容的如下一段內容:
<p>
<form action="/Home/ExamineTextBox" onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, { insertionMode: 0, updateTargetId: 'result' }); return false;"><input type="text" name="textBox1" id="textBox1" value="" />
<input type="submit" value="提交"/>
<span id="result"/>
</form>
</p>
正如你所想像的,在前面的編碼中,我們也完全可以直接使用這裡的Sys.Mvc.AsyncForm.handleSubmit函數,只是上面的形式更為直觀且便於使用罷了。
(三)添加控制器Action方法
然後,我們在Home控制器中添加一個Action方法ExamineTextBox,內容如下:
public class HomeController : Controller
{
public string ExamineTextBox(string textBox1)
{
string[] existingUsers = { "ScottGu", "ScottHa", "GuyIncognito", "Boris" };
if (existingUsers.Contains(username))
{
return "此名字已經被使用了!";
}
else
{
return "可以使用這個名字!";
}
}
}
注意,這裡ExamineTextBox的return方法返回的不是一個ActionResult類型,而是一個string。事實上,這個 string返回結果將會被自動打包成一個ContentResult類型。因此,你也可以直接返回一個ContentResult類型;但是,上面的編 程使得函數格式更為易於理解
另外值得注意的是,上面的方法返回的結果是經由AJAX調用實現的。之後,此結果被“悄悄地”填入到相應的span標記中。通過運行時啟動你的任何HTTP攔截工具,你會觀察到出現類似如下所示的請求(Request)內容:
POST /Home/ExamineTextBox HTTP/1.1
Referer: http://localhost.:45210/Home
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Accept-Encoding: gzip, deflate
Host: localhost.:45210
Content-Length: 28
Connection: Keep-Alive
Pragma: no-cache
textBox1=dude&__MVCAJAX=true
現在,我們來觀察一下響應(Response)結果,如下所示:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 39
Connection: Close
三、關於指令檔MicrosoftMvcAjax.debug.js
還記得前面的表單編碼中當調用Ajax.Form時出現一個UpdateTargetID嗎?它所指向的是按鈕控制項旁邊的div元素(相應於其 ID值)。其實,這個div元素內容的填入方式是通過指令檔MicrosoftMvcAjax.debug.js控制實現的。
為了進一步弄清楚問題的實質,我們還是跟蹤到指令檔MicrosoftMvcAjax.debug.js的內容中來看一下相關的代碼片斷吧,如下所示:
//把結果插入進目標元素中
if (targetElement) { //如果存在目標元素
switch (insertionMode) {
case Sys.Mvc.InsertionMode.Replace:
targetElement.innerHTML = executor.get_responseData();
break;
case Sys.Mvc.InsertionMode.InsertBefore:
targetElement.innerHTML = executor.get_responseData() + targetElement.innerHTML;
break;
case Sys.Mvc.InsertionMode.InsertAfter:
targetElement.innerHTML = targetElement.innerHTML + executor.get_responseData();
break;
}
}
四、把對Ajax指令碼的引用添加到母片視圖
注意,在目前(最新版本的Preview 4)的ASP.NET MVC編程中,我們必須手工添加相應的Ajax指令碼庫。在本例中,我把它們添加到母片視圖Site.Master下,如下所示:
<script src="/Content/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script src="/Content/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>
另外還請注意,上面的指令檔MicrosoftMvcAjax.js是架構最新提供的,它(以及另外幾個指令檔)位於你建立的MVC應用程式的Content檔案夾下。
五、小結
最後,請記住,本文中的項目是在ASP.NET MVC Preview 4下編寫和編譯通過的。從進一步分析ASP.NET MVC目前提供的幾個程式集不難看出,其目前提供的Ajax支援支援是非常有限的。目前從網上搜集到的有關於ASP.NET MVC架構內建的Ajax支援文章也非常罕見