ASP.NET MVC Model验证(三)
ASP.NET MVC Model验证(三)
前言
上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的Model验证是在哪个具体的方法中来执行的,本篇的主题就是模拟一下默认的实现,自定义个Model绑定器继承自DefaultModelBinder类型,并且重写某些个重要的方法。
Model验证
- Model验证简单运用示例
- ModelValidator使用生成过程
- 自定义实现DefaultModelBinder进行验证
- 自定义ModelValidatorProvider 和ModelValidator
- ValidationAttribute特性类使用
- 自定义ValidationAttribute特性类的示例实现
自定义实现DefaultModelBinder进行验证
以下用到的示例正是修改自ASP.NET MVC Model验证(一)篇幅中的示例,这里就不多说什么了,开始直接贴代码。
首先是ViewModel的定义,代码1-1。
代码1-1
namespace MvcApplication.Models { public class RegistrationInformation { public string ID { get; set; } public string UserID { get; set; } public string Password1 { get; set; } public string Password2 { get; set; } public string Name { get; set; } } }
控制器的定义,代码1-2:
代码1-2
public class ModelValidatorController : Controller { public ActionResult Index() { return View(new Models.RegistrationInformation()); } public ActionResult ModelValidator(RegistrationInformation regInfo) { return View(regInfo); } }
控制器方法对应视图定义,代码1-3:
代码1-3-1
Index视图
@model MvcApplication.Models.RegistrationInformation @{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm("ModelValidator","ModelValidator")) { <p>用户注册ID:@Html.EditorFor(m=>m.ID)</p> <p>用户名:@Html.EditorFor(m=>m.UserID)</p> <p>登录密码:@Html.EditorFor(m=>m.Password1)</p> <p>再次输入域密码:@Html.EditorFor(m=>m.Password2)</p> <p>姓名:@Html.EditorFor(m=>m.Name)</p> <input type="submit" value="提交" /> }
代码1-3-2
ModelValidator视图
@model MvcApplication.Models.RegistrationInformation @{ ViewBag.Title = "ModelValidator"; } <h2>ModelValidator</h2> @Html.ValidationSummary(true) <p>用户注册ID:@Html.EditorFor(m => m.ID) @Html.ValidationMessageFor(m=>m.ID) </p> <p>用户名:@Html.EditorFor(m => m.UserID) @Html.ValidationMessageFor(m=>m.UserID)</p> <p>登录密码:@Html.EditorFor(m => m.Password1) @Html.ValidationMessageFor(m=>m.Password1) </p> <p>再次输入域密码:@Html.EditorFor(m => m.Password2) @Html.ValidationMessageFor(m=>m.Password2) </p> <p>姓名:@Html.EditorFor(m=>m.Name)</p>
前面所示的就是把示例演示所需的定义好,这个时候运行会发现,只不过是一个页面传值而已,什么都没有发生。现在我们来定义一下自定义的Model绑定器继承自DefaultModelBinder类型。
代码1-4
public class MyCustomDefaultModelBinder : DefaultModelBinder
{
protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
{
base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value); switch (propertyDescriptor.Name)
{
case "ID":
if (string.IsNullOrEmpty((string)value) || (string)value == "")
{
bindingContext.ModelState.AddModelError("ID", "请输入ID,ID不能为空!");
}
break;
case "UserID":
if (string.IsNullOrEmpty((string)value) || (string)value == "")
{
bindingContext.ModelState.AddModelError("UserID", "请输入用户账户,用户账户不能为空!");
}
break;
case "Password1":
if (string.IsNullOrEmpty((string)value) || (string)value == "")
{
bindingContext.ModelState.AddModelError("Password1", "请输入登录密码,登录密码不能为空!");
}
break;
case "Password2":
if (string.IsNullOrEmpty((string)value) || (string)value == "")
{
bindingContext.ModelState.AddModelError("Pssword2", "请再次输入密码,密码不能为空!");
}
break;
case "Name":
break;
}
} protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
base.OnModelUpdated(controllerContext, bindingContext);
Models.RegistrationInformation regInfo = bindingContext.Model as Models.RegistrationInformation;
if (bindingContext.ModelState["Password1"].Errors.Count == && bindingContext.ModelState["Password2"].Errors.Count == )
{
if (regInfo.Password1 != regInfo.Password2)
{
bindingContext.ModelState.AddModelError("Password2", "请重新输入密码,与上次输入密码不同");
}
}
if (string.Compare(regInfo.Name, "jinyuan", true)==)
{
bindingContext.ModelState.AddModelError("", "您输入的名称违法了,立即更改不然查水表");
}
}
}
代码1-4中,我们重写了SetProperty()方法,从上篇的知识中得知,这个方法是在PropertyDescriptor类型的集合中遍历执行的,所以每次进入方法内部的只是个Model属性,而在SetProperty()方法内部的Model验证判断逻辑和ASP.NET MVC Model验证(一)篇幅的一样。
而在OnModelUpdated()方法中,我们首先获取了示例代码1-1中定义的ViewModel类型实例,这里有的朋友可能会问为什么不在SetProperty()方法中也这样使用,而是使用PropertyDescriptor类型的参数来进行验证操作,因为在SetProperty()方法执行的期间并没有对ViewModel完全的赋值,所以不能那样直接获取实例来使用。接着上面的说,在此之后从当前的绑定上下文的ModelState属性中获取判断密码1和密码2是否存在属性验证级的错误信息,没有的话将会对它们进行等值验证,正如上面代码所示的那样,随之验证Name的时候我将错误信息添加的键值为””,这表示默认为Model级验证错误信息。
所需要做的验证都做完了,注册我们的自定义绑定器到系统中,在Global.asax文件的Application_Start()中添加代码1-5.
代码1-5
ModelBinders.Binders.Add(typeof(Models.RegistrationInformation), new Binders.MyCustomDefaultModelBinder());
最后我们看一下效果图,图1表示为起初展示的页面,在我输入一部分的信息过后,点击提交过后页面会跳转到图2,并且执行完验证显示出验证后的错误信息。
图1
图2
大家可以动手试一试,到这里说明了一种验证方式,将在下篇为大家讲解MVC框架提供给我们的正儿八经用来执行验证的类型的一些相关类型,以及一些简单的示例,这样我们就不在使用Model绑定器来执行验证了,看起来绑定器有点不务正业。
作者:金源
出处:http://www.cnblogs.com/jin-yuan/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面
ASP.NET MVC Model验证(三)的更多相关文章
- ASP.NET MVC Model验证(四)
ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...
- 详解ASP.NET MVC Model验证
ASP.NET mvc的最好的优点之一就是支持Model验证,这个特性很方便你可以选择在定义Model的时候在字段中采用特性进行注解约定,也可以在代码中自己进行手动验证.下面就来细说一下ASP.NET ...
- ASP.NET MVC Model验证(五)
ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...
- ASP.NET MVC Model验证(二)
ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...
- ASP.NET MVC Model验证(一)
ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...
- ASP.NET MVC Model绑定(三)
ASP.NET MVC Model绑定(三) 前言 看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Mod ...
- ASP.NET MVC Model元数据(三)
ASP.NET MVC Model元数据(三) 前言 在上篇中我们大概的讲解了Model元数据的生成过程,并没有对Model元数据本身和详细的生成过程有所描述,本篇将会对详细的生成过程进行讲解,并且会 ...
- 【转】【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式
本文属转载,来源: http://www.byywee.com/page/M0/S868/868615.html 关于Model验证官方资料: http://msdn.microsoft.com/zh ...
- 【Asp.Net MVC】asp.net mvc Model验证总结及常用正则表达式
转自:http://www.cnblogs.com/easy5weikai/p/3843131.html 关于Model验证官方资料: http://msdn.microsoft.com/zh-cn/ ...
随机推荐
- 异常处理汇总 ~ 修正果带着你的Net飞奔吧!
经验库开源地址:https://github.com/dunitian/LoTDotNet 异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983 ...
- Lambda
Lambda Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可作为参数传递或作为函数调用值返回的本地函数. Lambda 表达式对于编写 LI ...
- 第一个移动前端开源项目-dailog
你还在为手机上没有忙碌光标而发愁吗?你还在抱怨弹出框组件要依赖zepto/jqery吗?你还在纠结是否要自己写一套还是去网上寻找成现成的UI组件吗?YouA为你轻松解决所有烦恼.YouA是我为移动前端 ...
- 在jekyll模板博客中添加网易云模块
最近使用GitHub Pages + Jekyll 搭建了个人博客,作为一名重度音乐患者,博客里面可以不配图,但是不能不配音乐啊. 遂在博客里面引入了网易云模块,这里要感谢网易云的分享机制,对开发者非 ...
- 当web.config文件放置在共享目录下(UNC),启动IIS会提示有错误信息500.19,伴随有错误代码0x80070003和错误代码0x80070005的解决办法
最近遇到一个很有意思的使用环境,操作人员将所有的网站应用内容投放到共享存储里面,并且使用微软的SMB协议将其以CIFS的方式共享出来,使用Windows Server 2008 R2的IIS将其连接起 ...
- Node.js学习笔记——Node.js开发Web后台服务
一.简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效.Node.j ...
- BPM与 SAP & Oracle EBS集成解决方案分享
一.需求分析 SAP和Oracle EBS都是作为全球顶级的的ERP产 品,得到了众多客户的青睐.然而由于系统庞大.价格昂贵以及定位不同,客户在实施过程中经常会面临以下困惑: 1.SAP如何实现&qu ...
- SharePoint 2016 必备组件离线安装介绍
前言 SharePoint 必备组件安装,一直以来都是SharePoint安装过程中的最大的坑,尤其是不能联网的服务器.博主在这里简单介绍一下离线安装过程,并附组件包下载以及安装命令,并且在windo ...
- Linux基础介绍【第五篇】
linux权限位 Linux文件或目录的权限位是由9个权限位来控制,每三位为一组,它们分别是文件属主权限.属组权限.其他用户权限. r:read可读权限,对应数字4: w:write可写权限,对应数字 ...
- 清除打印机队列中无法清除的任务 & 清空打印池
故障现象典型表现为以下两种情况 1.当打印任务开始进行时,这些打印任务便被保存在打印作业列表(也称打印队列)内.如果打印机因意外暂停(如打印机未连接)而未完成打印任务,则该打印任务将列入打印队列,并且 ...