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(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]+)*)[email protected][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进行多步验证。希望对你有所帮助,如果你有更好的方法,欢迎给我留言。

ASP.NET MVC中对Model进行分步验证的解决方法,布布扣,bubuko.com

时间: 2024-10-05 03:55:09

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

ASP.NET MVC 此安装不支持该项目类型解决方法

http://www.cnblogs.com/younggun/archive/2011/03/03/1969498.html ASP.NET MVC  此安装不支持该项目类型解决方法 打开 .csproject 文件  在  <ProjectTypeGuids>中的三个GUID的前两个修改为: {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21}; 后面还有一个 GUID 是你项目的GUID

asp.net mvc本地程序集和GAC的程序集冲突解决方法

一个从asp.net mvc 3升级到asp.net mvc 4的项目发生了如下错误: [A]System.Web.WebPages.Razor.Configuration.HostSection cannot be cast to [B]System.Web.WebPages.Razor.Configuration.HostSection. Type A originates from 'System.Web.WebPages.Razor, Version=1.0.0.0, Culture=n

[转]asp.net URL中包含中文参数造成乱码的解决方法

本文转自:http://www.jb51.net/article/22437.htm 问题: 前段时间,在系统中做了一个类似于友情链接的功能块,一直运行良好,直到有一天加了类似于以下的链接地址:http://www.****.com/user.aspx?id=水天,就出现大问题了: 1.从IE地址栏中直接输入这个地址,访问没错: 2.做一个静态页,其中包括这个超链接,点击访问也没错: 3.就是把这个链接添加到这个功能块中,点击访问那边接收到的是乱码. 一开始,被这个问题也搞得头大,在google

ASP.NET MVC中使用FluentValidation验证实体

1.FluentValidation介绍 FluentValidation是与ASP.NET DataAnnotataion Attribute验证实体不同的数据验证组件,提供了将实体与验证分离开来的验证方式,同时FluentValidation还提供了表达式链式语法. 2.安装FluentValidation FluentValidation地址:http://fluentvalidation.codeplex.com/ 使用Visual Studio的管理NuGet程序包安装FluentVa

ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器

ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器一:闲谈一下:1.现在任务跟踪管理系统已经开发快要结束了,抽一点时间来写一下,想一想自己就有成就感啊!!  2.关于任务跟踪管理系统项目中遇到的Windows服务以及Webservice的综合应用的问题. 大家好这是我第二次写博客 ,写的不好请大家多多谅解, 希望大家可以多多指正. 二:我稍微的整理了一下关于这个分布式定时器需求:1.根据任务跟踪管理系统中的数据库的AnswerSheet 表格中找到客户编

Asp.Net MVC中DropDownListFor的用法(转)

2016.03.04 扩展:如果 view中传入的是List<T>类型 怎么使用 DropList 既然是List<T> 那么我转化成 T  List<T>的第一个,最后一个不就是M吗? @Html.DropDownListFor(model=>model.First().Title, ViewData["Title"] as List<SelectListItem>, "标题", @"dropdown

ASP.NET MVC中使用窗体验证出现上下文的模型在数据库创建后发生更改,导致调试失败

在ASP.NET MVC中使用窗体验证.(首先要明白,验证逻辑是应该加在Model.View和Controller哪一个里面?由于Model的责任就是负责信息访问与商业逻辑验证的,所以我们把验证逻辑加在Model里面.) 第一步:引用下面这个命名空间 第二步:添加验证 第三步:启动调试,出现以下问题: 解决方法: 超链接中包含了解决这个问题的详细介绍,也就是通过Code First数据库迁移的方式让Entity Framework帮助我们自动调整数据库里面的架构. 解决这个问题最简单的方法就是将

关于asp.net MVC 中的TryUpdateModel方法

有比较才会有收货,有需求才会发现更多. 在传统的WebFormk开发工作中,我们常常会存在如下的代码块 //保存 protected void btnSubmit_Click(object sender, EventArgs e) { try { BLL.MoneyBll cun = new BLL.MoneyBll(); Model.Money m1 = new Model.Money(); m1.Commany = int.Parse(this.Commany.Text); m1.Count

在asp.net mvc中使用PartialView返回部分HTML段

问题链接: MVC怎样实现异步调用输出HTML页面 该问题是个常见的 case, 故写篇文章用于提示新人. 在asp.net mvc中返回View时使用的是ViewResult,它继承自ViewResultBase 同一时候它还有个兄弟PartialViewResult 相信聪明的你已经知道了它俩的差别了,没错 一个用于返回总体,还有一个返回局部(部分). 如果我有这样一个需求,输入username,然后返回相关信息.之前的做法可能会是用json格式来返回用户的相关信息,然后到页面去渲染相关 的