您的位置:首页 > 其它

MVC验证10-到底用哪种方式实现客户端服务端双重异步验证

2014-06-28 00:25 405 查看
原文:MVC验证10-到底用哪种方式实现客户端服务端双重异步验证本篇将通过一个案例来体验使用MVC的Ajax.BeginForm或jQuery来实现异步提交,并在客户端和服务端双双获得验证。希望能梳理、归纳出一个MVC异步验证的通用解决思路。本篇主要涉及:

1、通过Ajax.BeginForm()方式,返回部分视图显示验证信息。
2、通过jQuery+Html.BeginForm()方式,返回部分视图显示验证信息。
3、通过jquery,返回json字符串,json字符串中包含部分视图及验证信息。

此外,如下2篇是本文的"兄弟篇",只不过没有像本篇这样把多种实现方式放在一个案例中实现。

MVC验证08-jQuery异步验证:通过jquery,返回字符串,并把错误信息精确显示到指定html元素。
MVC验证09-使用MVC的Ajax.BeginForm方法实现异步验证:通过Ajax.BeginForm方式,返回部分视图显式验证信息。

准备工作

□实现客户端验证所需的js文件

不管js文件是放在_Layout.cshtml中,还是放在具体的视图页,也不管BundleConfig.cs中捆版了那些js和css。以下js文件是必须的:
1、jquery的某个版本
2、jquery.validate.js
3、jquery.validate.unobtrusive.js

□实现客户端验证的配置

在网站Web.config中,相关的属性必须设置为true:

<appSettings>

[code]...
<addkey="ClientValidationEnabled"value="true"/>

<addkey="UnobtrusiveJavaScriptEnabled"value="true"/>

</appSettings>

[/code]

□即将用到的ViewModel

usingSystem.ComponentModel.DataAnnotations;

[code]usingjan.Extension;

namespacejan.Models

{

publicclassCustomer

{

[Required]

[ValidUserNameAttribue(ErrorMessage="用户名只能为darren")]

[Display(Name="用户名")]

publicstringUserName{get;set;}

}

}

[/code]

□自定义验证特性ValidUserNameAttribue

usingSystem.ComponentModel.DataAnnotations;

[code]
namespacejan.Extension

{

publicclassValidUserNameAttribue:ValidationAttribute

{

publicoverrideboolIsValid(objectvalue)

{

//只有同时满足2个条件就让通过,否则验证失败

return(value!=null&&value.ToString()=="darren");

}

}

}

[/code]

1、通过Ajax.BeginForm方式,返回部分视图显示验证信息

□1、1Index.cshtml视图

如果把Index.cshtml看作主视图的话,需要异步获取的内容放在部分视图中,主视图通过Html.Partial()来显示部分视图内容。


@modeljan.Models.Customer

[code]
@{

ViewBag.Title="Index";

Layout="~/Views/Shared/_Layout.cshtml";

}


@DateTime.Now:Index.cshtml视图被渲染

<hr/>


<divid="FormContainer">

@Html.Partial("_Form")

</div>

[/code]

□1.2部分视图_Form.cshtml,验证失败返回的部分视图

用Ajax.BeginForm()方法实现。


@modeljan.Models.Customer

[code]
@DateTime.Now:_Form.cshtml视图被渲染

<hr/>


@using(Ajax.BeginForm("ValidCustomer",newAjaxOptions(){UpdateTargetId="FormContainer",OnSuccess="$.validator.unobtrusive.parse('form');"}))

{

<p>

@Html.LabelFor(m=>m.UserName):

@Html.EditorFor(m=>m.UserName)

</p>

<pstyle="color:red;">

@Html.ValidationMessageFor(m=>m.UserName)

</p>

<inputtype="submit"value="提交"/>

}


[/code]

UpdateTargetId="FormContainer"中的FormContainer是主视图的div,部分视图异步提交返回的内容显示到id为FormContainer的div中。
OnSuccess="$.validator.unobtrusive.parse('form');"每次提交完后再初始化表单,准备下一次被提交。

□1.3_Success.cshtml,验证成功返回的部分视图


@modeljan.Models.Customer

[code]@Model.UserName是有效的
[/code]

□1.4HomeController


usingSystem.Web.Mvc;

[code]usingjan.Models;

namespacejan.Controllers

{

publicclassHomeController:Controller

{

publicActionResultIndex()

{

returnView(newCustomer());

}


[HttpPost]

publicActionResultValidCustomer(Customercustomer)

{

returnPartialView(!ModelState.IsValid?"_Form":"_Success",customer);

}

}

}


[/code]

□1.5效果

提交之前:

展开usingSystem.IO;
usingSystem.Web.Mvc;

namespacejan.Extension
{
publicstaticclassControllerExtension
{
///<summary>
///把部分视图转换成string
///</summary>
///<paramname="controller">当前控制器</param>
///<paramname="viewName">当前部分视图名称</param>
///<returns>返回字符串</returns>
publicstaticstringRenderPartialViewToString(thisControllercontroller,stringviewName)
{
returncontroller.RenderPartialViewToString(viewName,null);
}

///<summary>
///把部分视图转换成string
///</summary>
///<paramname="controller">当前控制器</param>
///<paramname="viewName">当前部分视图</param>
///<paramname="model">Model</param>
///<returns>返回字符串</returns>
publicstaticstringRenderPartialViewToString(thisControllercontroller,stringviewName,objectmodel)
{
if(string.IsNullOrEmpty(viewName))//如果部分视图名称没有
viewName=controller.ControllerContext.RouteData.GetRequiredString("action");//action名称就是部分视图名称

controller.ViewData.Model=model;

using(varsw=newStringWriter())
{
//根据控制器上下文和部分视图名称得到ViewEngineResult
varviewResult=ViewEngines.Engines.FindPartialView(controller.ControllerContext,viewName);

//根据控制器的上下文+ViewData+ViewEngineResult中的View构建ViewContext对象实例
varviewContext=newViewContext(controller.ControllerContext,viewResult.View,controller.ViewData,controller.TempData,sw);

//把ViewContext对象实例写到流中
viewResult.View.Render(viewContext,sw);

//把流中的内容转成string
returnsw.GetStringBuilder().ToString();
}
}
}
}


■3.4.4=HomeController中,验证失败,返回自定义部分视图


usingSystem.Web.Mvc;

[code]usingjan.Extension;
usingjan.Models;

usingSystem.Threading;


namespacejan.Controllers

{

publicclassHomeController:Controller

{

publicActionResultIndex()

{

returnView(newCustomer());

}


[HttpPost]

publicActionResultValidCustomer(Customercustomer)

{

Thread.Sleep(2000);

if(!ModelState.IsValid)

{

//returnJson(new{vd=false,pv=this.RenderPartialViewToString("_Form",customer)});

returnJson(new{vd=false,pv=this.RenderPartialViewToString("CustomerView",customer)});

}

returnJson(new{vd=true,pv=this.RenderPartialViewToString("_Success",customer)});

}

}

}


[/code]

当第二次提交错误信息时,不会跳转:




总结

当涉及到表单异步提交的:
1、优先考虑使用MVC自带的Ajax.BeginForm()方法,较快。
2、其次考虑"jQuery+Html.BeginForm()方式",较慢,因为需要等待Html.BeginForm()提交。

当涉及不到表单,只涉及部分属性异步提交的:
1、优先考虑“MVC验证08-jQuery异步验证”:通过jquery,返回字符串,并把错误信息精确显示到指定html元素。
2、其次考虑本篇的"通过jquery,返回json字符串,json字符串中包含部分视图及验证信息"。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐