ASP.NET MVC中对Model进行分步验证的解决方法
原文:ASP.NET MVC中对Model进行分步验证的解决方法
在我之前的文章: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(, 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 = "", Text = "Step1" },
new SelectListItem { Value = "", Text = "Step2" },
new SelectListItem { Value = "", Text = "Step3" },
new SelectListItem { Value = "", 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 "":
step1.enable();
step2.disable();
step3.disable();
step4.disable();
break;
case "":
step1.disable();
step2.enable();
step3.disable();
step4.disable();
break;
case "":
step1.disable();
step2.disable();
step3.enable();
step4.disable();
break;
case "":
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去实现的。看下面代码。
validate: function Sys_Mvc_FormContext$validate(eventName) {
var fields = this.fields;
var errors = [];
for (var i = ; i < fields.length; i++) {
var field = fields[i];
if (!field.elements[].disabled) {
var thisErrors = field.validate(eventName);
if (thisErrors) {
Array.addRange(errors, thisErrors);
}
}
}
if (this.replaceValidationSummary) {
this.clearErrors();
this.addErrors(errors);
}
return errors;
}
}
在第6行代码加入了一句判断:当页面的元素没有被disabled的时候才去验证。
好了这样就实现了一次只对Model中的几个属性字段进行验证。
运行:
asp.net mvc的验证机制只对model中当前页面的属性进行验证:

填写正确通过验证:

总结:本文解决了我之前遗留下来的一个问题。实现了在ASP.NET MVC中对Model进行多步验证。希望对你有所帮助,如果你有更好的方法,欢迎给我留言。
ASP.NET MVC中对Model进行分步验证的解决方法的更多相关文章
- ASP.NET MVC中默认Model Binder绑定Action参数为List、Dictionary等集合的实例
在实际的ASP.NET mvc项目开发中,有时会遇到一个参数是一个List.Dictionary等集合类型的情况,默认的情况ASP.NET MVC框架是怎么为我们绑定ASP.NET MVC的Actio ...
- asp.net MVC中的@model与Model
asp.net MVC中的@model与Model https://blog.csdn.net/ydm19891101/article/details/44301201 在MVC的实际使用中,我们经常 ...
- ASP.NET MVC 此安装不支持该项目类型解决方法
http://www.cnblogs.com/younggun/archive/2011/03/03/1969498.html ASP.NET MVC 此安装不支持该项目类型解决方法 打开 .csp ...
- ASP.NET MVC 中CSS JS压缩合并 功能的使用方法
通过压缩合并js文件和css文件,可以减少 服务器的响应 次数和 流量,可以大大减小服务器的压力,对网站优化有比较明显的帮助!压缩合并 css 文件和js文件是网站优化的一个 比较常用的方法. ASP ...
- asp.net mvc本地程序集和GAC的程序集冲突解决方法
一个从asp.net mvc 3升级到asp.net mvc 4的项目发生了如下错误: [A]System.Web.WebPages.Razor.Configuration.HostSection c ...
- [转]asp.net URL中包含中文参数造成乱码的解决方法
本文转自:http://www.jb51.net/article/22437.htm 问题: 前段时间,在系统中做了一个类似于友情链接的功能块,一直运行良好,直到有一天加了类似于以下的链接地址:htt ...
- Asp.net MVC中提交集合对象,实现Model绑定
Asp.net MVC中的Model自动绑定功能,方便了我们对于request中的数据的处理, 从客户端的请求数据,自动地以Action方法参数的形式呈现.有时候我们的Action方法中想要接收数组类 ...
- Asp.net MVC中提交集合对象,实现Model绑定(转载)
Asp.net MVC中的Model自动绑定功能,方便了我们对于request中的数据的处理, 从客户端的请求数据,自动地以Action方法参数的形式呈现.有时候我们的Action方法中想要接收数组类 ...
- 在ASP.NET MVC中使用IIS级别的URL Rewrite
原文 在ASP.NET MVC中使用IIS级别的URL Rewrite 大约一年半前,我在博客上写过一系列关于URL Rewrite的文章(2.3.4),把ASP.NET平台上进行URL Rewrit ...
随机推荐
- RH133读书 笔记(5) - Lab 5 User and Group Administration
Lab 5 User and Group Administration Goal: To build skills for user and group administration. Estimat ...
- POJ 2828 Buy Tickets(排队问题,线段树应用)
POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意: 排队买票时候插队. 给出一些数对,分别代表某个人的想要插入的位 ...
- php方法综述除去换行符(PHP_EOL使用变量)
一个小包裹,事实上,不同的平台具有不同的实现.为什么要这样.它可以是一个世界是多样的. 最初unix与世界把它包/n取代,但windows为了体现自己的不同.要使用/r/n,更有意思的是,mac随着/ ...
- FreeBSD包管理
FreeBSD软件没有安装Ubuntu的apt-get.它也不是Gentoo的portage.有三种方式: package ports 自主进行源代码编译安装 这里简介前两种. FreeBSD 6.0 ...
- jQuery -> 获取各种滤芯(filter)
按顺序选择 依次选择过滤器(filter)有着 :first 第一元件 :last 最后一个元素 :even 序号为偶数的元素 :odd 序号为奇数的元素 :eq(n) 序号等于n的元素 :lt(n) ...
- [ACM] HDU 2295 Radar (二分法+DLX 重复覆盖)
Radar Problem Description N cities of the Java Kingdom need to be covered by radars for being in a s ...
- Youtube最佳Red5 官方视频下载指南,字幕【亲测成功】
前言 最近在研究Red5 流媒体服务框架,官网上的信息足以让一个新手入门 有官方參考手冊 -- 高速了解red5的相关信息 有Red5 on Stackoverflow -- 在上面能够提问或者回答 ...
- NSIS:禁止选择安装路径和编辑安装目录
原文 NSIS:禁止选择安装路径和编辑安装目录 如果你想在安装包中禁止用户选择安装路径和编辑安装目录,有两种方式. 第一种:注释或删除安装目录选择页面 1 ;!insertmacro MUI_PA ...
- 使用批处理给IIS添加MIME类型
原文 使用批处理给IIS添加MIME类型 @echo off set /p warn="警告:本脚本会清空全部站点原有MIME类型,输入y按回车继续,直接回车退出:" if & ...
- GridView网格线都设置
如今,做网上商店的商品陈列,我想用网络格布局,但总认为空好看.所以我想给它一个净加格线.但是,我遇到了一个问题,网络格布局其实很easy,是集GridView布局和背景颜色adapter布局设置背景颜 ...