在ASP.NET MVC beta发布之前,M$就宣布支持开源的JS框架jQuery,然后ASP.NET MVC beta发布后,你建立一个ASP.NET MVC beta的项目后,你可以在项目的scripts目录下找到ASP.NET AJAX和jQuery的JS。反正我是比较喜欢jQuery的,所以对于M$此举还是挺欣慰的。
废话不多说,我们使用AJAX来实现发表评论的功能吧。先来看看怎样使用M$的JS框架来进行异步AJAX请求。
首先,当然是要引入M$的AJAX框架的JS:
< script src ="/Content/MicrosoftMvcAjax.js" type ="text/javascript" ></ script >
ASP.NET MVC的框架的Helper方法中提供了对他自身的AJAX的支持,使用的是System.Web.Mvc.Ajax命名空间下面的方法。你可以这样写代 码:
或者:
在AjaxHelper中并没有EndForm方法,你可以直接写Html来关闭form,或者你也可以使用Html.EndForm();来关 闭。好,下面我们来写发表评论的AjaxForm:
这里详细说下AjaxOptions的可选配置的各个属性的作用。
public string HttpMethod :就是指定请求的Http方法, " POST " " GET " " PUT " 等等
public InsertionMode InsertionMode :返回的内容要更新的目标元素的方式。有三种方式:
Replace : 替换目标元素里面的内容;
InsertBefore :返回内容插入到目标元素的前面;
InsertAfter:返回内 容插入到目标元素的后面。
public string LoadingElementId :指定在进行异步请求的时 候要显示的提示信息的Loading元素的ID
public string OnBegin :在发送异步请求前触发的 JavaScript方法
public string OnComplete :在发送异步请求完成后触发的 JavaScript方法
public string OnFailure :在发送异步请求失败的时候触发的 JavaScript方法
public string OnSuccess :在发送异步请求成功的时候触发的 JavaScript方法
public string UpdateTargetId :指定返回的内容要更新的目标 元素的ID
public string Url :请求的URL,不指定则 为form的action的url。
在上面的代码中,在异步请求成功后会调用名称为clearComment的JavaScript方法来清除输入框的评论内容,然后返回内容会替换掉 id为boxcomments元素里面的内容。完整的客户端代码如下:
< div class ="entry" >
<%
Html.RenderPartial( " _commentList " , ViewData.Model.Comments);
if (BlogSettings.Instance.IsCommentsEnabled){
Ajax.BeginForm( " AddComment " , new { controller = " Home " , id = "" }, new AjaxOptions()
{
HttpMethod = " Post " ,
LoadingElementId = " loading " ,
// OnBegin = " commentValidate " ,
OnSuccess = " clearComment " ,
UpdateTargetId = " boxcomments " ,
InsertionMode = InsertionMode.Replace
}, new { id = " commentform " });
%>
< h3 id ="respond" > 发表评论 </ h3 >
< p > 欢迎留下你的评论,你的支持,是我最大的动力! </ p >
< p >< label for ="author" > Name (required) </ label >
< input type ="text" tabindex ="1" size ="22" value ="" id ="author" name ="author" />
<% = Html.ValidationMessage( " Author " ) %> </ p >
< p >< label for ="email" > E-mail (will not be published) (required) </ label >
< input type ="text" size ="22" tabindex ="2" value ="" id ="email" name ="email" />
<% = Html.ValidationMessage( " Email " ) %> </ p >
< p >< label for ="url" > Website </ label >
< input type ="text" tabindex ="3" size ="22" value ="" id ="Website" name ="Website" /></ p >
< p > <% = Html.ValidationMessage( " Content " ) %>
< textarea tabindex ="4" rows ="10" cols ="5" id ="commentContent" name ="content" ></ textarea ></ p >
< p >< input type ="submit" value ="Submit Comment" tabindex ="5" id ="submit" name ="submit" />
< span id ="loading" style ="display:none;" > 数据处理中 </ span >
< input type ="hidden" value ="<%= ViewData.Model.Id %>" id ="comment_post_ID" name ="comment_post_ID" /></ p >
</ form >
< script type ="text/javascript" language ="javascript" >
function clearComment(a, b, c, d) {
$get( " commentContent " ).value = "" ;
}
</ script >
<% } %>
</ div >
以上为使用M$的AJAX框架来实现AJAX异步请求,下面来看看使用jQuery怎么做呢。前面说过,我个人比较喜欢jQuery,所以示例的 4mvcBlog里面的将使用jQuery来实现。
首先,我们用jQuery写一个用于提交form表单的异步请求的小"插件":
$.fn.ajaxForm = function (success) {
var form = $( this );
var btn = form.find( " :submit " );
form.submit( function () {
$.ajax( {
url: form.attr( " action " ),
type: form.attr( " method " ),
data: form.serialize(),
beforeSend: function (xhr) {
btn.attr( " disabled " , true );
showLoading();
} ,
success: function (data) {
if (success) { success(data); }
} ,
error: function () {
alert( " 请求出错,请重试 " );
} ,
complete: function () {
btn.attr( " disabled " , false );
hideLoading();
}
} );
return false ;
} );
} ;
function showLoading() {
$( " #loading " ).css( " display " , "" );
} ;
function hideLoading() {
$( " #loading " ).css( " display " , " none " );
} ;
} )(jQuery);
然后我们不需要修改原来的一般的form,我们只需要使用ajaxForm 方法来指定要进行ajax请求的form的id就可以了:
< h3 id ="respond" > 发表评论 </ h3 >
< p > 欢迎留下你的评论,你的支持,是我最大的 动力! </ p >
< p >< label for ="author" > Name (required) </ label >
< input type ="text" tabindex ="1" size ="22" value ="" id ="author" name ="author" />
<% = Html.ValidationMessage( " Author " ) %> </ p >
< p >< label for ="email" > E-mail (will not be published) (required) </ label >
< input type ="text" size ="22" tabindex ="2" value ="" id ="email" name ="email" />
<% = Html.ValidationMessage( " Email " ) %> </ p >
< p >< label for ="url" > Website </ label >
< input type ="text" tabindex ="3" size ="22" value ="" id ="Website" name ="Website" /></ p >
< p > <% = Html.ValidationMessage( " Content " ) %>
< textarea tabindex ="4" rows ="10" cols ="5" id ="commentContent" name ="content" ></ textarea ></ p >
< p >< input type ="submit" value ="Submit Comment" tabindex ="5" id ="submit" name ="submit" />
< span id ="loading" style ="display:none;" > 数据处理中 </ span >
< input type ="hidden" value ="<%= ViewData.Model.Id %>" id ="comment_post_ID" name ="comment_post_ID" /></ p >
</ form >
< script type ="text/javascript" language ="javascript" >
// 我们只需要在这里注册一下事件就可 以,这就是jQuery和Html干净的分离的优雅。
$( " #commentform " ).ajaxForm(success);
function success(data) {
if (data.search( / ^/{[/s/S]+/}$ / img) > - 1 ) {
alert(eval( " ( " + data + " ) " ).ErrorMsg.toString());
} else {
var c = $( " .boxcomments " );
if (c.length <= 0 ) {
c = $( ' <div class="boxcomments"></div> ' );
c.insertBefore( " #commentform " );
}
c.html($(data).find( " .boxcomments " ).html());
$( " #commentContent " ).val( "" );
}
}
</ script >
后台代码如下:
[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Put), CallByAjax( true )]
public ActionResult AddCommentByAjax(FormCollection form)
{
JsonResultData jsonData = new JsonResultData();
Comment comment = new Comment();
string postId = form[ " comment_post_ID " ] ?? "" ;
Post post = Post.GetPost( new Guid(postId));
if (TryUpdateModel(comment, new [] { " Content " , " Author " , " Email " }))
{
if (comment.IsValid)
{
comment.Id = Guid.NewGuid();
comment.Author = Server.HtmlEncode(comment.Author);
// comment.Email = email;
comment.Content = Server.HtmlEncode(comment.Content);
comment.IP = Request.UserHostAddress;
// comment.Country = country;
comment.DateCreated = DateTime.Now;
comment.Parent = post;
comment.IsApproved = ! BlogSettings.Instance.EnableCommentsModeration;
if (User.Identity.IsAuthenticated)
comment.IsApproved = true ;
string website = form[ " Website " ] ?? "" ;
if (website.Trim().Length > 0 )
{
if ( ! website.ToLowerInvariant().Contains( " :// " ))
website = " http:// " / + website;
Uri url;
if (Uri.TryCreate(website, UriKind.Absolute, out url))
comment.Website = url;
}
post.AddComment(comment);
SetCommentCookie(comment.Author, comment.Email, website, comment.Country);
return View( " _commentList " , post.Comments);
}
else
{
foreach ( string key in comment.BrokenRules.Keys)
{
// 将验证不通过的信息添加到错误信息列表
jsonData.ErrorMsg.Add(comment.BrokenRules[key]);
}
}
}
jsonData.IsError = true ;
return Json_Net(jsonData); // 如果业务逻辑验证不通过,则返回JSON结果表示的失败信息
}
对于上面的后台代码的[CallByAjax(true)]特性你可以参考我Asp.net Mvc Preview 5 体验--实现ActionSelectionAttribute来判断是否为AJAX请求而选择不同的Action 这一篇文章。
暂时就到这里吧。Enjoy!具体效果请下载示例代码运行查看或到演示站点http://4mvcblog.qsh.in/ 查看。