ASP.NET MVC中对Model进行分步验证的解决方法

    在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个Model的信息,但是又分页面填写信息的,当时我加上ModelState.IsValid这句验证代码的时候,根本没法通过验证,因为在注册的前面三步,注册用户的Model信息都没填写完整,而ModelState.IsValid是对一个实体的所有属性进行判断验证的。当时很纠结,因为刚接触Asp.net MVC,故没有找到解决方案。这篇文章将给出解决的办法。看下面需要验证的Model的代码如下:

代码
publicclass UserViewModel
{
[DisplayName(
"step")]
[Required(ErrorMessage
="You must select a step .")]
publicint Step { get; set; }
//个人信息
[Required(ErrorMessage ="姓名不能为空")]
[StringLength(
20, ErrorMessage ="姓名长度不能超过20个字符")]
publicstring Name { get; set; }

[RegularExpression(
@"120|((1[0-1]|\d)?\d)", ErrorMessage ="年龄格式不对")]
publicint? Age { get; set; }

//职位信息
[Required(ErrorMessage ="职位不能为空")]
publicstring Post { get; set; }
publicint? Salary { get; set; }

//学历信息
[Required(ErrorMessage ="毕业院校不能为空")]
publicstring University { get; set; }
publicint? GraduationYear { get; set; }

//联系信息
[Required(ErrorMessage ="邮件不能为空")]
[RegularExpression(
@"^[a-z][a-z|0-9|]*([_][a-z|0-9]+)*([.][a-z|"+@"0-9]+([_][a-z|0-9]+)*)?@[a-z][a-z|0-9|]*\.([a-z]"+@"[a-z|0-9]*(\.[a-z][a-z|0-9]*)?)$", ErrorMessage="邮件格式不正确")]
publicstring Email { get; set; }
publicint? Mobile { get; set; }

public IEnumerable<SelectListItem> StepList { get; set; }

public UserViewModel()
{
var list
=new List<SelectListItem>() {
new SelectListItem { Text ="(Select)" },
new SelectListItem { Value ="1", Text ="Step1" },
new SelectListItem { Value ="2", Text ="Step2" },
new SelectListItem { Value ="3", Text ="Step3" },
new SelectListItem { Value ="4", Text ="Step4" }
};
this.StepList =new SelectList(list, "Value", "Text");
}


}

实现:

    这篇文章这种情况服务端和客户端的验证都会讲到。为了简化起见,这里我除去的WF的流程功能,直接用下拉框表示,当下拉框选择step1表示填写第一步注册的信息,当下拉框选择step2表示填写第二步注册的信息,当下拉框选择step3表示填写第三步注册的信息,当下拉框选择step4表示填写第四步注册的信息。写得很啰嗦,但是这个很容易实现,我使用Jquery来显示和隐藏下拉框对应的Step。Jquery代码如下:

代码
<script type="text/javascript">
$(
function () {
$.fn.enable
=function () {
returnthis.show().removeAttr("disabled");
}

$.fn.disable
=function () {
returnthis.hide().attr("disabled", "disabled");
}
var dllStep = $("#Step");
var step1 = $("#Step1,#Step1 input");
var step2 = $("#Step2,#Step2 input");
var step3 = $("#Step3,#Step3 input");
var step4 = $("#Step4,#Step4 input");
setControls();

dllStep.change(
function () {
setControls();
});

function setControls() {
switch (dllStep.val()) {
case"1":
step1.enable();
step2.disable();
step3.disable();
step4.disable();
break;
case"2":
step1.disable();
step2.enable();
step3.disable();
step4.disable();
break;
case"3":
step1.disable();
step2.disable();
step3.enable();
step4.disable();
break;
case"4":
step1.disable();
step2.disable();
step3.disable();
step4.enable();
break;
case"":
step1.disable();
step2.disable();
step3.disable();
step4.disable();
break;
}
}
});
</script>

如下图:

第一步:填写姓名和年龄。

 第二步:填写职位和薪水

 第三步填写:毕业院校和毕业时间

第四步填写:邮箱和电话

    为了实现这样的验证,我们可以将验证的错误信息中移除不在当前步骤填写的字段的错误信息,写一个类InputValidationModelBinder继承DefaultModelBinder并重载OnModelUpdated方法,将不必要的错误信息清除,代码如下:

publicclass InputValidationModelBinder : DefaultModelBinder
{
protectedoverridevoid OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var modelState
= controllerContext.Controller.ViewData.ModelState;
var valueProvider
= controllerContext.Controller.ValueProvider;

var keysWithNoIncomingValue
= modelState.Keys.Where(x =>!valueProvider.ContainsPrefix(x));
foreach (var key in keysWithNoIncomingValue)
modelState[key].Errors.Clear();
}
}

     上面是服务端的代码,对于客户端,我们都知道asp.net MVC客户端验证时通过MicrosoftMvcValidation.js去实现的。看下面代码。

1 validate: function Sys_Mvc_FormContext$validate(eventName) {
2 var fields =this.fields;
3 var errors = [];
4 for (var i =0; i < fields.length; i++) {
5 var field = fields[i];
6 if (!field.elements[0].disabled) {
7 var thisErrors = field.validate(eventName);
8 if (thisErrors) {
9 Array.addRange(errors, thisErrors);
10 }
11 }
12 }
13 if (this.replaceValidationSummary) {
14 this.clearErrors();
15 this.addErrors(errors);
16 }
17 return errors;
18 }
19 }

在第6行代码加入了一句判断:当页面的元素没有被disabled的时候才去验证。

好了这样就实现了一次只对Model中的几个属性字段进行验证。

运行:

asp.net mvc的验证机制只对model中当前页面的属性进行验证:

填写正确通过验证:

总结:本文解决了我之前遗留下来的一个问题。实现了在ASP.NET MVC中对Model进行多步验证。希望对你有所帮助,如果你有更好的方法,欢迎给我留言。 



(全文完)


以下为广告部分

您部署的HTTPS网站安全吗?

如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

SSL检测评估

快速了解HTTPS网站安全情况。

安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

SSL证书工具

安装部署SSL证书变得更方便。

SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

SSL漏洞检测

让服务器远离SSL证书漏洞侵扰

TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

posted @ 2010-09-27 00:16  麒麟  阅读(8612)  评论(9编辑  收藏  举报