一起谈.NET技术,ASP.NET MVC中对Model进行分步验证的解决方法

简介:   在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个Model的信息,但是又分页面填写信息的,当时我加上ModelState.IsValid这句验证代码的时候,根本没法通过验证,因为在注册的前面三步,注册用户的Model信息都没填写完整,而ModelState.IsValid是对一个实体的所有属性进行判断验证的。

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

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

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

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

// 学历信息
[Required(ErrorMessage = " 毕业院校不能为空 " )]
public string University { get ; set ; }
public int ? 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 = " 邮件格式不正确 " )]
public string Email { get ; set ; }
public int ? 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 () {
return this .show().removeAttr( " disabled " );
}

$.fn.disable
= function () {
return this .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方法,将不必要的错误信息清除,代码如下:

 
 
public class InputValidationModelBinder : DefaultModelBinder
{
protected override void 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进行多步验证。希望对你有所帮助,如果你有更好的方法,欢迎给我留言。 

目录
相关文章
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
41 0
|
1月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
29 0
|
1月前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
5 0
|
1月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
95 5
|
3月前
|
XML 前端开发 定位技术
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
25 0
|
3月前
|
前端开发
.net core mvc获取IP地址和IP所在地(其实是百度的)
.net core mvc获取IP地址和IP所在地(其实是百度的)
123 0
|
5月前
|
开发框架 自然语言处理 前端开发
基于ASP.NET MVC开发的、开源的个人博客系统
基于ASP.NET MVC开发的、开源的个人博客系统
52 0
|
8月前
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
114 0
|
9月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
[回馈]ASP.NET Core MVC开发实战之商城系统(三)
67 0
|
9月前
|
开发框架 前端开发 .NET
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
[回馈]ASP.NET Core MVC开发实战之商城系统(一)
113 0