ASP.NET MVC学习之模型验证篇

2014-05-28 11:36 by y-z-f, 6722 阅读, 13 评论, 收藏编辑

一.学习前的一句话

在这里要先感谢那些能够点开我随笔的博友们。慢慢的已经在博客园中度过一年半了,伊始只是将博客园作为自己学习的记录本一样使用,也不敢将自己的随笔发表到博客园首页,生怕自己的技艺不高,反倒成了笑话。但是随着时间的推移,再也按捺不住这种想法,于是就写了一篇随笔发表到博客园首页。让我意想不到的是有许多人都看了,而且也留下了评论。这让我鼓起勇气写了第二、三、四篇。到现在的连载,这里我希望那些从未发表过随笔的人可以尝试去发表,在这里他人不会嘲讽你,而是会给你更好的建议。说了这么多下面我们继续开始学习ASP.NET MVC吧。

二.准备工作

1、创建一个ASP.NET MVC 4网站(笔者的命名是MvcStudy)

2、在Models下创建一个Register模型类,具体代码如下所示:

  1.  

3、创建一个名为Home的控制器,并在其中写入下面的代码:

4、接着在Views下创建一个Home文件夹并在其中新建一个Index视图,代码如下:

5、因为后面要用到客户端验证,所以这里我们先把需要引用需要的js库(在Views/Shared/_Layout.cshtml中写入):

PS:为了确保正确,请读者验证下web.config中的以下属性的值是否跟笔者的一样:

三.常规验证

相信很多从事ASP.NET的开发者在对数据的验证上基本都是用的ASP.NET自带的验证控件,同时在后台还会通过N多个if语句再去判断,所以在ASP.NET MVC的常规验证跟这个一样,唯一的区别就是错误的信息输出不需要我们自己实现了,下面我们修改Home控制器中的Index(Register reg)动作:

  1. 1 [HttpPost]
  2. 2 public ActionResult Index(Register reg)
  3. 3 {
  4. 4 if (String.IsNullOrEmpty(reg.UserName))
  5. 5 {
  6. 6 ModelState.AddModelError("UserName", "用户名不能为空");
  7. 7 }
  8. 8 else if (reg.UserName.Length < 6)
  9. 9 {
  10. 10 ModelState.AddModelError("UserName", "用户名长度不能小于6位");
  11. 11 }
  12. 12 if (ModelState.IsValidField("BirthDate") && reg.BirthDate > DateTime.Now)
  13. 13 {
  14. 14 ModelState.AddModelError("BirthDate", "生日不能为将来的时间");
  15. 15 }
  16. 16 if (ModelState.IsValid)
  17. 17 {
  18. 18 //保存数据
  19. 19 }
  20. 20 return View();
  21. 21 }

上面我们简单的判断了用户名是否为空,长度是否小于6,以及出生日期是否填写的为将来的日期,接着我们还要在Index视图中加入@Html.ValidationSummary(),这样我们才能够看到最后的输出的错误信息,编译然后不输入任何内容点击注册之后将会出现下面的情况:

我们会发现表单压根就提交不了,这是因为客户端验证在工作。获取读者会很奇怪这节只是常规验证,这个是因为出生日期的格式是DateTime是不能为NULL的,而ASP.NET MVC默认情况下就已经为我们做好了。随便输入123到出生日期然后点击注册,页面会反馈下面的错误信息:

第一个信息就是我们在控制器中通过if判断语句加进去的,而第二个似乎你会困惑是怎么回事,这是因为模型绑定器中会为我们进行简单的验证,比如日期不能为空,并且日期的格式要正确,这个都是默认的行为。我们可以尝试在用户名中输入123,同时出生日期输入2020/1/1,点击注册,这时候的错误信息都是我们添加的了:

读者使用过很多系统,错误信息基本上都是显示在对应的输入框的右边,在ASP.NET MVC中一样可以判断,下面我们修改Index视图:

这个时候我们在重新提交,错误信息就到右边了。但是笔者还不打算结束掉这节,我如果限制用户名不能为100000怎么办呢?或许读者马上就能写出来,但是这个是模型级的错误,并不是针对这个字段,所以我们在Home控制器的Index方法(响应Post的那个)中继续追加:

接着修改Index视图:

然后重新编译,用户名输入100000就可以看到下面的结果:

这样我们就可以结束这节了。

四.采用注解属性的验证

上面这种方式的验证虽然简单,很多人都能够立马上手,但是看到动作中N多个if语句的确不是个滋味,在这个炎炎夏日会让人非常暴躁,这节我们就来简单的方法来解决这些问题,为我们降温,我们修改Register模型类:

  1. 1 namespace MvcStudy.Models
  2. 2 {
  3. 3 public class Register
  4. 4 {
  5. 5 [Required(ErrorMessage="用户名必须填写")]
  6. 6 [MinLength(6,ErrorMessage="用户名长度过短")]
  7. 7 public String UserName { get; set; }
  8. 8 [DataType(DataType.Password)]
  9. 9 public String Password { get; set; }
  10. 10 [DataType(DataType.Password)]
  11. 11 [Compare("Password",ErrorMessage="密码要一致")]
  12. 12 public String RptPassword { get; set; }
  13. 13 public String Email { get; set; }
  14. 14 public DateTime BirthDate { get; set; }
  15. 15 public bool IsApprove { get; set; }
  16. 16 }
  17. 17 }

笔者在这里还判断了密码和重复密码是否相同,关于DataType可以参考笔者写的模型绑定,下面重新编译,然后打开页面测试,就可以发现这些验证都实现了,因为笔者这里默认开启了客户端验证所以在未验证通过的情况下无法提交表单。但是我们发现现有的验证注解属性没法实现显示出生日期不能为将来实现,所以下面一节我们还要学习自定义验证注解属性。

五.自定义验证注解属性

通过上节我们已经能够使用ASP.NET MVC自带的验证属性来完成一些简单的验证,正如上节最后所说的那样,对于一部分验证自带的已经无法满足我们的需求了,那么我们就需要通过自定义的方式来解决,下面我们自定义一个注解属性来解决上节遗留下来的问题,首先我们新建一个Validation文件夹,然后在该文件夹下面新建一个FutureTimeAttribute类,代码如下所示:

  1. 1 namespace MvcStudy.Validation
  2. 2 {
  3. 3 public class FutureTimeAttribute : ValidationAttribute
  4. 4 {
  5. 5 public override bool IsValid(object value)
  6. 6 {
  7. 7 DateTime dt = (DateTime)value;
  8. 8 if (dt != null)
  9. 9 {
  10. 10 if (dt < DateTime.Now)
  11. 11 {
  12. 12 return true;
  13. 13 }
  14. 14 }
  15. 15 return false;
  16. 16 }
  17. 17 }
  18. 18 }

接着我们就可以运用到对应的属性上面了

重新编译,然后填写一个将来的时间点击注册之后我们将会看到如下的结果:

通过这节的补充,相信大家此时此刻酷爽吗?当然还有一部分人还需要更实现更复杂的验证判断,而且是针对特定的模型类实现的,并不适合采用上面这种方式,那么下节会非常符合你的胃口。

PS:读者不仅仅可以通过继承ValidationAttribute,同时还可以继承其他现有的验证注解属性,比如RequiredAttribute等。

六.模型与验证合二为一

我们可以发现笔者之前不是显示用户名不能为100000吗,但是我并没有将这个作为注解属性而写,因为注解属性一般适合于很多地方都需要使用这种验证才适合,但是这个限制仅仅只是针对这个模型类,而其他的模型类并不需要。那么我们就需要一中能够与模型类紧密相关的验证,而解决方案就是让模型类实现IValidatableObject接口的Validate方法即可,比如下面笔者将实现限制用户名不能为100000的情况:

然后我们重新编译,用户名输入为100000就可以看到这个错误了:

七.客户端验证

其实前面几节一直都在使用客户端验证,本该这节是不需要的,但是我们可以发现邮箱部分还没有验证,读者可能会认为应该使用RegularExpression来验证,但是学过jquery验证库的人应该知道这个库已经自带了专门的验证,而这节就是用来手动使用这个验证的,我们打开Index视图修改邮箱部分:

  1. 1 <div>
  2. 2 邮箱:
  3. 3 @Html.TextBoxFor(m => m.Email, new
  4. 4 {
  5. 5 data_val = "true",
  6. 6 data_val_email = "邮箱格式错误",
  7. 7 data_val_required = "请输入邮箱"
  8. 8 })
  9. 9 @Html.ValidationMessageFor(m => m.Email)
  10. 10 </div>

刷新页面,这个时候我们发现邮箱也可以验证了:

相信很多喜欢客户端开发而不是服务端开发人员来说,这种方式对于你们来说更快捷,但是对于服务端开发者来说,并不需要气馁,ASP.NET MVC也提供对应的方法,下节我们将用服务端的方式来实现同样的效果。

八.自定义客户端验证

这里笔者就不多说废话了直接上代码,我们自己实现一个邮箱验证属性,而且还能够支持客户端验证,首先在Valudation文件夹下新建一个EmailAttribute类,并在其中写入如下代码:

PS:为了能够符合本节,所以笔者就没有将服务端的验证代码写到其中,如果读者需要在真实场合中使用务必将服务端的验证也要加上去。

下面我们就在Email中加上这个注解属性并重新编译,我们可以看到最后页面的效果跟上一节的效果是完全一致的。

原文地址:http://www.cnblogs.com/yaozhenfa/p/asp_net_mvc_model_validation.html

ASP.NET MVC学习之模型验证详解的更多相关文章

  1. Asp.Net MVC学习总结之过滤器详解(转载)

    来源:http://www.php.cn/csharp-article-359736.html   一.过滤器简介 1.1.理解什么是过滤器 1.过滤器(Filters)就是向请求处理管道中注入额外的 ...

  2. ASP.NET MVC学习之模型验证篇

    一.学习前的一句话 在这里要先感谢那些能够点开我随笔的博友们.慢慢的已经在博客园中度过一年半了,伊始只是将博客园作为自己学习的记录本一样使用,也不敢将自己的随笔发表到博客园首页,生怕自己的技艺不高,反 ...

  3. ASP.NET MVC学习之模型绑定(1)

    一.前言 下面我们将开始学习模型绑定,通过下面的知识我们将能够理解ASP.NET MVC模型的模型绑定器是如何将http请求中的数据转换成模型的,其中我们重点讲述的是表单数据. 二.正文 1.简单类型 ...

  4. Asp.Net MVC 扩展 Html.ImageFor 方法详解

    背景: 在Asp.net MVC中定义模型的时候,DataType有DataType.ImageUrl这个类型,但htmlhelper却无法输出一个img,当用脚手架自动生成一些form或表格的时候, ...

  5. Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证

    概要 在asp.net webform开发中经常会对用户提交输入的信息进行校验,一般为了安全起见大家都会在客户端进行Javascript(利于交互).服务端双重校验(安全).书写校验代码是一个繁琐的过 ...

  6. ASP.NET MVC学习之模型绑定(2)

    3.手工调用模型绑定 很多情况下我们都是通过形参的方式接收来自http流中的数据,这看似是完美的,但是缺少了很多过程中的控制,所以我们就需要使用手工的方式进行绑定.下面我们通过一个例子来说明,首先打开 ...

  7. ASP.NET MVC 4 (十) 模型验证

    模型验证是在模型绑定时检查从HTTP请求接收的数据是否合规以保证数据的有效性,在收到无效数据时给出提示帮助用户纠正错误的数据. 显式模型验证 验证数据最直接的方式就是在action方法中对接收的数据验 ...

  8. ASP.NET MVC学习之模型模板篇

    一.前言 如果你使用ASP.NET MVC制作后台一定会爱上它的EditorForModal.DisplayForModal和LabelForModal方法,因为这些方法可以将模型直接变成对应的标签, ...

  9. Asp.Net MVC part2 View、Controller详解

    View详解Razor视图引擎简介HtmlHelper强类型页面 Razor视图引擎简介强大的@:表示使用C#代码,相当于aspx中的<%%>可以完成输出功能当遇到html标签时会认为C# ...

随机推荐

  1. count++线程安全与 synchronized对性能影响的测试

    一个计时器,同时开启100个线程,每个线程休眠1ms钟后,将全局静态变量count加1,这100个线程创建完之后,休眠500ms,计算总耗时,程序如下: public class Counter { ...

  2. 【MySQL报错】ERROR 1558 (HY000): Column count of mysql.user is wrong. Expected 43, found 39.

    原文参考:http://wuzhuti.cn/2348.html 之前在centos6.4系统安装的是自带的mysql 5.1版本,后来升级到了5.6版本,执行以下命令报错 在网上查找原因说说因为升级 ...

  3. cdoj842-天下归晋 【树状数组】

    http://acm.uestc.edu.cn/#/problem/show/842 天下归晋 Time Limit: 3000/1000MS (Java/Others)     Memory Lim ...

  4. RigidBody组件的Is Kinematic

    RigidBody组件的Is Kinematic属性打上勾(设为true,使其不受物理引擎驱动,Wall是为了防止其移动,Person是为了防止其受到力不断旋转—看的心塞=v=) .is kinema ...

  5. 带环链表 linked list cycle

    1 [抄题]: 给定一个链表,判断它是否有环. [思维问题]: 反而不知道没有环怎么写了:快指针fast(奇数个元素)或fast.next(偶数个元素) == null [一句话思路]: 快指针走2步 ...

  6. .net为图片添加水印(转) jpg png和gif格式

    .net为图片添加水印(转) jpg png和gif格式 .net为图片添加水印(转) jpg png和gif格式,转自csdn的hyde82,现在跟大家一起来分享下: 利 用.net中System. ...

  7. discuz模板介绍

    1.discuz目录下template为模板目录 模板套系 discuz每套模板,支持不同的风格,而多个风格组成一套套系. 推荐使用复制的方法创建新的风格 (*默认的公共页面静态资源,存储在discu ...

  8. UI设计必用工具 — AI快捷键大全

    01 常用工具 V 选择工具 A 直接选择工具 Y 魔棒工具 Q 套索工具 P 钢笔工具 Z 缩放工具 R 旋转工具 O 镜像工具 M 矩形工具 L 椭圆工具 B 画笔工具 N 铅笔工具 C 剪刀工具 ...

  9. QFileInfo

    https://www.cnblogs.com/findumars/p/10247573.html

  10. OSGi karaf scheduler

    OSGi karaf scheduler karaf 中提供了定时任务管理,只需安装 feature:install scheduler 即可,然后在 karaf 容器中发布 org.apache.k ...