原文: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 ...
随机推荐
-
swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
-
Html文档流和文档对象模型DOM理解
前言 在理解浮动和定位时,触碰到文档流概念.为了更好理解浮动和定位,学习了文档流和DOM(文档对象模型). 正文 DOM(文档对象模型)简单理解就是编写的html页面所有内容构成的树形结构.例如: 根 ...
-
Unity3D 自定义事件(事件侦听与事件触发)
先来看下效果图,图中点击 Cube(EventDispatcher),Sphere(EventListener)以及 Capsule(EventListener)会做出相应的变化,例子中的对象相互之间 ...
-
基于HTML5的3D网络拓扑自动布局
上篇将HT for Web的3D拓扑弹力布局的算法运行在Web Workers后台(http://www.hightopo.com/blog/70.html),这篇我们将进一步折腾,将算法运行到真正的 ...
-
VS 控件命名规范
基本数据类型 数据类型 数据类型简写 标准命名举例 Array arr arrShoppingList Boolean bln blnIsPostBac ...
-
MySQL 127.0.0.1和localhost本质区别
登录方式: [root@10-4-14-168 ~]# mysql -uroot -p Enter password: 查看权限表 mysql> SELECT user,host,passwor ...
-
android apk 的root 权限和USB adb 权限的差别
USB adb 权限是指,当adb 连接手机时,手机中的守护进程adbd 的权限为root 权限,从而它的子进程也具有root 权限.通常假设adb shell 看到是: Android 4.0 以后 ...
-
16.C++-初探标准库
在别人代码里,经常看到std命名空间,比如使用std命名空间里的标准输入输出流对象cout: #include<iostream> using namespace std; int mai ...
-
c# Lambda操作类封装
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...
-
[vue]vue基础复习项案例stepbystep
看本篇第二次复习内容即可. 还有一些 文档了这个如 https://www.cnblogs.com/iiiiiher/p/9508733.html https://www.cnblogs.com/ii ...