一起谈.NET技术,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(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进行多步验证。希望对你有所帮助,如果你有更好的方法,欢迎给我留言。 

时间: 2024-09-20 00:22:08

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

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

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

asp.net URL中包含中文参数造成乱码的解决方法_实用技巧

问题: 前段时间,在系统中做了一个类似于友情链接的功能块,一直运行良好,直到有一天加了类似于以下的链接地址:http://www.****.com/user.aspx?id=水天,就出现大问题了: 1.从IE地址栏中直接输入这个地址,访问没错: 2.做一个静态页,其中包括这个超链接,点击访问也没错: 3.就是把这个链接添加到这个功能块中,点击访问那边接收到的是乱码. 一开始,被这个问题也搞得头大,在google了一把后,总算是把问题给搞清楚了,其实只要这个链接地址不经过任何编码传递是不会有问题的

Asp.net Ajax 中的脚本错误: Sys未定义 的解决方法

ajax|asp.net|错误|脚本|解决         提前祝大家新年好!前段时间日夜赶工,终于按计划推出了项目的新版本.今天终于有时间写点东西了.         前段时间公司同事在项目中引入了Asp.net Ajax (beta1)版. 用着用着,在查看网页时,不时报 'Sys'未定义 的错误.按照网上的办法对web.confg 做了一翻手术,一点效果也没有.想想也对,web.config跟本没改动过,凭什么突然就把问题都算在人家头上?经过一翻摸索后,突然发现,原来是身份验证惹的祸.在配

Asp.net Ajax中的脚本错误“Sys未定义”的解决方法

提前祝大家新年好!前段时间日夜赶工,终于按计划推出了项目的新版本.今天终于有时间写点东西了. 前段时间公司同事在项目中引入了Asp.net Ajax (beta1)版. 用着用着,在查看网页时,不时报 'Sys'未定义 的错误.按照网上的办法对web.confg 做了一翻手术,一点效果也没有.想想也对,web.config跟本没改动过,凭什么突然就把问题都算在人家头上?经过一翻摸索后,突然发现,原来是身份验证惹的祸.在配置了身份验证的网站中,访问未登录页面时,对Ajax脚本资源的访问被拒绝,转向

在Linux中使用MD5实现用户验证的解决方法_Linux

使用openssl中的MD5函数,该函数返回16字节的unsigned char类型的数据,每个字节的范围都在0-255间,把 它格式化为十六进制就是32位md5编码.注:一个字节为8位,正好可以表示2位的十六进制. 使用登录客户端的用户名从Redis数据库中得到salt值和加密后的密码,然后把登录客户端的密码经过salt加密后,与 Redis数据库中的密码进行比较.相同则验证通过,否则验证失败. Redis数据库中密码的存储格式为password:salt 用户验证算法如下: int user

在ASP.NET MVC中使用IIS级别的URL Rewrite

原文 在ASP.NET MVC中使用IIS级别的URL Rewrite 大约一年半前,我在博客上写过一系列关于URL Rewrite的文章(2.3.4),把ASP.NET平台上进行URL Rewrit的方式和各自地特点进行了较为详细的描述.应该来说,已经讲的非常具体,可以应对90%的情况.其实IIS Rewrite的原理非常容易理解,进行一些简单的变化和推断之后,便可以得出一些问题的原因和解决方案.现在我们就来看一个真实案例:在ASP.NET MVC中使用IIS级别的URL Rewrite. 在

包含在ASP.NET MVC中的过滤器

在深入研究如何编写过滤器之前,首先看看包含在ASP.NET MVC中的过滤器. ASP.NET MVC包括了如下3种即开即用的动作过滤器: Authorize:该过滤器用于限制对控制器或控制器动作的访问. HandleError:该过滤器用来指定一个处理异常的动作,这个异常是从动作方法的内部抛出的. OutputCache:该过滤器用来为动作方法提供输出的缓存. 接下来将依次深入讨论这3个过滤器. 1  Authorize AuthorizeAttribute是包含在ASP.NET MVC中默认

一起谈.NET技术,ASP.NET MVC中对数据进行排序的方法

本系列是讲解如何在asp.net mvc中对数据进行展示.排序.分页等的系列文章.在上周的文章中,一步一步教会了大家如何使用ASP.NET MVC框架去的展示数据.在上周的文章中,我们先用Visual Studio创建了一个新的ASP.NET MVC应用程序,接着连接到了Northwind数据库,并展示了如何使用微软的LINQ-SQL的工具去访问数据库中的数据,接着指导如何去实现视图层去展示产品信息及如何设计控制器. 本文是在上一篇文章的例子基础上,展示了如何去实现数据的双向排序.如果你是已经熟

一起谈.NET技术,在ASP.NET MVC中进行TDD开发

TDD介绍 TDD是一种开发方法,全称是Test-Driven development,中文是测试驱动开发.作者是Kent Beck.首先让我介绍一下三种常见的开发方式: 第一种:先Coding,然后Bug Fix. 第二种:先Coding,然后Unit Test,最后Bug Fix.很显然用了单元测试的比第一种开发方式要好不少. 第三种:就是本文要说的TDD,它的方式和第二种恰恰相反.TDD先设计单元测试,然后再Coding,最后修复Bug.看下图: TDD开发过程可以看成:给制自己制定一个目