【ASP.NET MVC系列】浅谈数据注解和验证

 

【01】浅谈Google Chrome浏览器(理论篇)

【02】浅谈Google Chrome浏览器(操作篇)(上)

【03】浅谈Google Chrome浏览器(操作篇)(下)

【04】浅谈ASP.NET框架

【05】浅谈ASP.NET MVC运行过程

【06】浅谈ASP.NET MVC 控制器

【07】浅谈ASP.NET MVC 路由

【08】浅谈ASP.NET MVC 视图

【09】浅谈ASP.NET MVC 视图与控制器传递数据

【10】浅谈jqGrid 在ASP.NET MVC中增删改查

【11】浅谈ASP.NET 页面之间传值的几种方式

【12】浅谈缓存技术在ASP.NET中的运用

【13】浅谈NuGet在VS中的运用

【14】浅谈ASP.NET 程序发布过程

【15】浅谈数据注解和验证

【16】浅谈依赖注入

【17】浅谈表单和HTML辅助方法

【18】浅谈基于APS.NET身份验证

【19】浅谈ASP.NET MVC 模型

【20】浅谈ASP.NET MVC 单元测试

【21】浅谈ASP.NET MVC网络安全;

【22】浅谈ASP.NET MVC八大类扩展

【23】再谈ASP.NET MVC Routing

【24】浅谈ASP.NET 高级话题

【25】浅谈大型ASP.NET MVC项目(含DEMO)

【26】下一系列:ASP.NET WebAPI

一  概述

关于数据验证和数据注解,是任何软件系统不可小觑的必要模块,在软件系统中起到举足轻重的作用。

1.从数据验证的验证方式来说,我们一般分为客户端验证和服务端验证(或者两种方式相结合);

2.从数据验证的作用角度来说,数据验证起到很重要的作用,如防止漏洞注入,防止网络攻击(XSS等),确保数据安全,确保数据合理性,防止垃圾数据等作用;

3.从数据验证的种类来书,一般分为第三方验证(如我们用Jquery写好验证插件,在客户端用AJAX验证)和基于ASP.NET MVC框架的数据验证;

4.从数据注解的作用角度来说,如界面关键字段的友好设置和提示等;

说了那么多,那么本篇文章会讲解哪些内容呢?

本篇文章主要讲解基于ASP.NET MVC框架的数据验证特性和数据注解。

二  数据验证

(一)ASP.NET MVC 内置六大类数据验证特性

1.在ASP.NET MVC中,验证特性定义在System.ComponentModel.DataAnnotations命名空间中,因此我们在使用验证特性前,需要引入命名空间:

using System.ComponentModel.DataAnnotations;

2.ASP.NET MVC内置了六大验证特性:Required,StringLength,RegularExpression,Range,Compare和Remote;

3.数据验证使用单个验证特性:指数据验证只使用其中一个验证特性

1 [Required]
2  public string Username { get; set; }

4.有些属性,单个验证特性无法满足,需要两个及其以上验证特性组合,如密码,至少要满足两个条件:

(1)必填      (2)不少于6位

[Required]
[StringLength(6)]
 public string Password { get; set; }

5.用代码演示一下五大验证特性(Remote除外)

Models:UserInfo.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5
 6 using System.ComponentModel.DataAnnotations;
 7
 8
 9 namespace DataValidate.Models
10 {
11     public class UserInfo
12     {
13         //定义用户名必填
14         [Required]
15         public string UserName { get; set; }
16         //定义密码必填,且满足6位
17         [Required]
18         [StringLength(128,MinimumLength =6)]
19         public string Password { get; set; }
20         //验证两次输入的密码是否一致
21         [Required]
22         [Compare("Password", ErrorMessage = "两次密码输入不一致")]
23         public string ConfirmPassword { get; set; }
24         //定义邮件为必填,且满足邮件格式
25         [Required]
26         [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
27         public string Email { get; set; }
28         //定义年龄为必填,且1-130岁之间
29         [Required]
30         [Range(1, 130)]
31         public int Age { get; set; }
32     }
33 }
34
35  

Controller:DefaultController

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6
 7 using DataValidate.Models;
 8 namespace DataValidate.Controllers
 9 {
10     public class DefaultController : Controller
11     {
12         // GET: Default
13
14         public ActionResult Index()
15         {
16             return View();
17         }
18
19         public ActionResult DataValidateDemo(UserInfo userInfo)
20         {
21             UserInfo _userInfo = new UserInfo();
22             _userInfo.UserName = userInfo.UserName;
23             return View("Index");
24         }
25     }
26 }

View:Index.cshtml

 1 @model DataValidate.Models.UserInfo
 2
 3
 4 @{
 5     ViewBag.Title = "Index";
 6 }
 7
 8 <h2>Index</h2>
 9
10 @using (Html.BeginForm("DataValidateDemo", "Default"))
11 {
12     <div>@Html.Label("用户名"): @Html.TextBoxFor(m=>m.UserName)
13     @Html.ValidationMessageFor(m=>m.UserName)
14     </div>
15     <div>@Html.Label("密码"):@Html.TextBox("Password")
16     @Html.ValidationMessageFor(m=>m.Password)</div>
17
18     <div>@Html.Label("确认密码"):@Html.TextBox("ConfirmPassword")
19     @Html.ValidationMessageFor(m=>m.ConfirmPassword)</div>
20     <div>
21         @Html.Label("邮件"):@Html.TextBox("Email")
22         @Html.ValidationMessageFor(m => m.Email)
23     </div>
24     <div>
25         @Html.Label("年龄"):@Html.TextBox("Age")
26         @Html.ValidationMessageFor(m => m.Age)
27     </div>
28     <div><input type="submit" value="提交" /></div>
29 }

我们来看看测试结果

6.为什么要把Remote剔出来单独讲解呢?

我们知道,除Remote以外的五大验证特性,命名空间均为System.ComponentModel.DataAnnotations,而Remote特性的命名空间却是System.Web.Mvc。

Remote,从字面意思可以看出,“远程”,即远程验证。Remote特性指利用服务器端的回调函数执行客户端的验证逻辑(当执行到有Remote特性的元数据时,会自动地调用相应的控制器下的Action)。

举个例子:新会员注册时,一般手机号是不允许重复的,检查DB中是否已存在手机号,可以使用Remote特性来验证。

Model:UserInfo.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5
 6 using System.ComponentModel.DataAnnotations;
 7
 8
 9 namespace DataValidate.Models
10 {
11     public class UserInfo
12     {
13         //定义用户名必填
14         [Required]
15         public string UserName { get; set; }
16         //定义密码必填,且满足6位
17         [Required]
18         [StringLength(128,MinimumLength =6)]
19         public string Password { get; set; }
20         //验证两次输入的密码是否一致
21         [Required]
22         [Compare("Password", ErrorMessage = "两次密码输入不一致")]
23         public string ConfirmPassword { get; set; }
24         //定义邮件为必填,且满足邮件格式
25         [Required]
26         [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
27         public string Email { get; set; }
28         //定义年龄为必填,且1-130岁之间
29         [Required]
30         [Range(1, 130)]
31          public int Age { get; set; }
32
33         [Required]
34         [System.Web.Mvc.Remote("CheckTelephone", "Default", ErrorMessage ="手机号码已经存在")]
35         public string Telephone { get; set; }
36     }
37 }
38
39  

DefaultController

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Web;
 5 using System.Web.Mvc;
 6
 7 using DataValidate.Models;
 8 namespace DataValidate.Controllers
 9 {
10     public class DefaultController : Controller
11     {
12         // GET: Default
13
14         public ActionResult Index()
15         {
16             return View();
17         }
18
19         public ActionResult DataValidateDemo(UserInfo userInfo)
20         {
21             UserInfo _userInfo = new UserInfo();
22             _userInfo.UserName = userInfo.UserName;
23             return View("Index");
24         }
25
26         public ActionResult CheckTelephone(string telephone)
27         {
28             if (telephone=="13636595489")
29             {
30                 return Json("手机号"+telephone+ "已经存在", JsonRequestBehavior.AllowGet);
31             }
32             return Json(true, JsonRequestBehavior.AllowGet);
33
34         }
35     }
36 }

Index.cshtml

 1 @model DataValidate.Models.UserInfo
 2
 3
 4 @{
 5     ViewBag.Title = "Index";
 6     Html.EnableClientValidation();
 7     Html.EnableUnobtrusiveJavaScript();
 8
 9 }
10
11
12 <h2>Index</h2>
13
14 @using (Html.BeginForm("DataValidateDemo", "Default"))
15 {
16     <div>
17         @Html.Label("用户名"): @Html.TextBoxFor(m => m.UserName)
18         @Html.ValidationMessageFor(m => m.UserName)
19     </div>
20     <div>
21         @Html.Label("密码"):@Html.TextBox("Password")
22         @Html.ValidationMessageFor(m => m.Password)
23     </div>
24
25     <div>
26         @Html.Label("确认密码"):@Html.TextBox("ConfirmPassword")
27         @Html.ValidationMessageFor(m => m.ConfirmPassword)
28     </div>
29     <div>
30         @Html.Label("邮件"):@Html.TextBox("Email")
31         @Html.ValidationMessageFor(m => m.Email)
32     </div>
33     <div>
34         @Html.Label("年龄"):@Html.TextBox("Age")
35         @Html.ValidationMessageFor(m => m.Age)
36     </div>
37     <div>
38         @Html.Label("手机号码"):@Html.TextBox("Telephone")
39         @Html.ValidationMessageFor(m => m.Telephone)
40     </div>
41     <div><input type="submit" value="提交" /></div>
42 }
43 @section scripts{
44
45     <script src="~/Scripts/jquery.validate.js"></script>
46     <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
47 }

测试结果:

 给大家留一个思考题:如何验证多个参数?

在实际项目开发中,一般我们验证的不仅仅是一个参数,而是多个参数,如用户名和手机号,身份证号等一起验证,关于多参数验证,Remote验证特性又是怎么处理的呢?

(二) 验证错误提示

1.什么是验证错误提示?

指验证字段在验证不通过时,反馈给用户的提示信息,如密码不能低于6位,手机号必须为11位,年龄限制在1-130岁之间等,通过验证特性的ErroMessage实现。

[Required]
[StringLength(128,MinimumLength =6,ErrorMessage ="密码不能低于6位数")]

2.错误验证提示大致分为两大类:默认错误提示和自定义错误提示。

(1)默认错误提示:当我们不指定ErroMessage的值时,ASP.NET MVC框架会指定默认值。

//定义密码必填,且满足6位
[Required]
[StringLength(128,MinimumLength =6)]
 public string Password { get; set; }

Result:

(2)自定义值:我们为ErrorMessage指定具体自定义的值“密码不能低于6位数”

[Required]
[StringLength(128,MinimumLength =6,ErrorMessage ="密码不能低于6位数")]
 public string Password { get; set; }

Result:

3.为什么要有自定义错误提示?

(1)为用户呈现友好提示,我们来看一下2中的默认值和自定义值;

默认值:字段Password必须是一个字符串,其最小长度为6,最大长度为128(这么一句话,要是给不懂程序的用户看了,肯定会疯掉,

很简单,对程序员来说,“字段”二字再基础不过,可对用户来说,他可能会问,字段是什么东东?)

自定义值:密码不能低于6位数(无论是程序员还是用户,都能看得明白)

(2)提高通用性,比如对美国提供英语提示,对俄罗斯提供俄语提示等;

4.如何实现通用性国际化?

在如上的自定义验证错误提示中,我们使用的是硬编码的形式,然而,面向国际市场开发的,这种硬编码错误消息提示是不实用的,因为我们要为不同地区显示

不同内容,实现国际化,庆幸的是,所有验证特性都允许为本地化的错误消息提示指定资源类型名称和资源名称,感兴趣的读者朋友,请参照How to:Set the

Cultrue and UI Cultrue for ASP.NET Page Globalization(sites:http://msdn.microsoft.com/en-us/library/bz9tc508.aspx)

 思考题,如何实现错误消息通用性国际化?

(三)  验证原理

关于数据验证,我们思考这样一个问题:验证是什么时候发生的?如何才能知道验证失败?

本节我们将来回答这个问题。

1.要想充分理解验证原理,我们应该先熟悉几个基本概念:模型绑定器,模型元数据,模型验证器和模型状态(这部分内容,本篇文章不论述,大家知道这几个概念即可,具体详情内容,

将在接下来的文章中与大家分享:【ASP.NET MVC系列】浅谈ASP.NET MVC 模型)

2.默认情况下,ASP.NET MVC框架在模型绑定时就执行验证逻辑,在执行验证时,分为隐式执行和显示执行。

(1)隐式执行:一般指在控制器的Action中带有参数时,就会隐式执行模型验证。如下方法带有参数,因此就隐式执行模型绑定。

1 public ActionResult DataValidateDemo(UserInfo userInfo)
2         {
3             UserInfo _userInfo = new UserInfo();
4             _userInfo.UserName = userInfo.UserName;
5             return View("Index");
6         }

(2)显示执行:只利用控制器的UpdateModel或TryUpdateModel方式时,显示执行模型绑定。

3.模型绑定器一旦使用新值更新模型属性时,就会利用当前的模型元数据获得模型的所有验证器;

4.ASP.NET MVC运行时,DataAnnotationsModelValidator与数据验证一起工作;

5.DataAnnotationsModelValidator验证器会找到所有的验证特性并执行它所包含的验证逻辑;

6.模型绑定器捕获所有失败的验证规则,并把他们放入模型状态中;

7.模型绑定主要的副产品是模型状态,模型状态包含如下内容:

(1)包含用户放入模型属性中的所有值;

(2)包含每个属性相关联的所有错误;

(3)包含所有与模型对象本身有关的错误;

8.如果模型状态中存在错误,ModelState.IsValid就返回false;

9.控制操作和验证错误是怎样执行的?

控制器操作决定模型验证失败和验证成功时的执行流程。

(1)验证成功时:当验证成时,操作通常会执行必要的步骤来保存或更新用户信息;

(2)验证失败时:当验证失败时,操作一般会重新渲染提交模型值得视图;

(四)自定义验证

ASP.NET MVC之所以强大,在于其提供强大的自定义和扩展性,关于这个内容,会在后续的文章:“【SP.NET MVC系列】浅谈ASP.NET MVC八大类扩展”中深入讲解这两个强大的特性。

1.基于ASP.NET MVC的自定义验证,一般分为两大类型:将验证逻辑封装在自定义数据中和将验证逻辑封装在模型对象中。

(1)将验证逻辑封装在自定义数据中:复杂,但可复用性高;

(2)将验证逻辑封装在模型对象中:简单,但可复用性低;

2.将验证逻辑封装在自定数据中(会在后续的文章:“【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展”中深入讲解)

3.将验证逻辑封装模型对象中(会在后续的文章:“【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展”中深入讲解)

三 数据注解

(一)七大类型ASP.NET MVC内置数据注解

1.Dispaly特性:(1)模型属性设置友好的显示名称  (2)控制UI上属性的显示顺序;

2.ScaffoldColumn特性:隐藏HTML辅助方法;

3.DisplayFormat特性:处理属性的各种格式化选项;

4.ReadOnly特性:确保默认的模型绑定器不使用新值来更新;

5.DataType特性:提供关于属性的特定信息;

6.UIHint特性:(1)为ASP.NET MVC运行时提供模板名称,以备调用模板辅助方法渲染输出时使用  (2)自定义模板辅助方法;

7.HiddenInput特性:渲染type为hidden的元素;

四   参考文献

【01】ASP.NET MVC5 高级编程(Jon Galloway,Brad Wilson,K.Scott Allen,David Matson 著 ,孙远帅 译)

【02】ASP.NET MVC5编程实战(第3版)(Dino Esposite 著,潘丽丞 译)

五   版权区

  • 感谢您的阅读,若有不足之处,欢迎指教,共同学习、共同进步。
  • 博主网址:http://www.cnblogs.com/wangjiming/。
  • 极少部分文章利用读书、参考、引用、抄袭、复制和粘贴等多种方式整合而成的,大部分为原创。
  • 如您喜欢,麻烦推荐一下;如您有新想法,欢迎提出,邮箱:2098469527@qq.com。
  • 可以转载该博客,但必须著名博客来源。

【ASP.NET MVC系列】浅谈数据注解和验证的更多相关文章

  1. 【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  2. MVC学习手册之数据注解与验证

    MVC学习手册之数据注解与验证 新建一个MVC5的WEB应用程序,VS2013会自动生成一段代码,以下是Account控制器下Register.cshtml 页面的代码: @model WebAppl ...

  3. ASP.NET MVC5高级编程 之 数据注解和验证

    客户端验证逻辑会对用户向表单输入的数据给出一个即时反馈.而之所以需要服务器端验证,是因为来自网络的信息都是不能被信任的. 当在ASP.NET MVC设计模式上下文中谈论验证时,主要关注的是验证模型的值 ...

  4. 【ASP.NET MVC系列】浅谈ASP.NET MVC 视图与控制器传递数据

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  5. 【ASP.NET MVC系列】浅谈NuGet在VS中的运用

    一     概述 在我们讲解NuGet前,我们先来看看一个例子. 1.例子: 假设现在开发一套系统,其中前端框架我们选择Bootstrap,由于选择Bootstrap作为前端框架,因此,在项目中,我们 ...

  6. 【ASP.NET MVC系列】数据验证和注解

    [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作篇)(下) [04]浅谈ASP. ...

  7. 【ASP.NET MVC系列】浅谈表单和HTML辅助方法

    [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作篇)(下) [04]浅谈ASP. ...

  8. 【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)

    lASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操 ...

  9. 【ASP.NET MVC系列】浅谈ASP.NET 页面之间传值的几种方式

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

随机推荐

  1. Codeforces 811 A. Vladik and Courtesy

    A. Vladik and Courtesy   time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  2. HDU 2537 8球胜负(模拟)

    /*这是一个模拟题,模拟一种台球的进球过程,并且判定胜负. 对于输入的字符串,如果出现R则红方记1分,如果出现Y则黄方记1分. 最后根据哪一方打进黑球和得分情况判定胜负. 程序说明: 这里给出两个C语 ...

  3. python3爬取百度图片(2018年11月3日有效)

    最终目的:能通过输入关键字进行搜索,爬取相应的图片存储到本地或者数据库 首先打开百度图片的网站,搜索任意一个关键字,比如说:水果,得到如下的界面 分析: 1.百度图片搜索结果的页面源代码不包含需要提取 ...

  4. NOIP2014飞扬的小鸟

    长为n,高为m的二维平面,其中有k个管道(忽略管道的宽度)小鸟始终在游戏界面内移动.从最左边任意高度位置出发,到达游戏界面最右边,游戏完成每个单位时间沿横坐标方向右移距离为1,竖直移动的距离由玩家控制 ...

  5. Codeforces #432 Div2 D

    #432 Div2 D 题意 给出一些数字,如果这些数字的的 \(gcd\) 不为1则称这些数字 \(good\). 可以有两种操作: 花费 x 删掉一个数 花费 y 将一个数加 1 问使这些数 \( ...

  6. [CTSC2017]吉夫特(Lucas定理,DP)

    送70分,预处理组合数是否为偶数即可. 剩下的数据,根据Lucas定理的推论可得当且仅当n&m=n的时候,C(n,m)为奇数.这样就可以直接DP了,对于每个数,考虑它对后面的数的影响即可,直接 ...

  7. 【指数型母函数】hdu1521 排列组合

    #include<cstdio> #include<cstring> using namespace std; int n,m,jiecheng[11]; double a[1 ...

  8. 【2-SAT(两次DFS版)】BZOJ1823-[JSOI2010]满汉全席

    [题目大意] 有n个材料,m个评委.每种材料可以被用来做满族菜或汉族菜,m个评委有两种可以让他满意的猜中.问是否可以满足所有评委要求? [思路] 每天只能做三道题,我已经是一个废人了……(葛优躺.jp ...

  9. Swift,简单语法

    1.创建变量 var a=0 //变量 let b=0 //常量 let b:String="你好" //:后可以定义类型(变量一旦定义,类型不可改变)(类型不填Swift会自动判 ...

  10. JAVA常见算法题(二十七)

    题目:给定一个存放整数的数组,请写一个算法,把偶数移动到该数组的右边,奇数放在该数组的左边,请考虑时间和空间的最优算法. package com.forezp.util; /** * 题目:给定一个存 ...