一、;引言
如果你详细研究一下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支持文章也非常罕见。作为参考,读者不妨再研究一下这篇博客文章
http://www.singingeels.com/Articles/AJAX_Panels_with_ASPNET_MVC.aspx。
标签: 编程