ASP.NET MVC5----数据注解和验证
在使用MVC模式进行开发时,数据注解是经常使用的(模型之上操作),下面是我看书整理的一些常见的用法。
什么是验证,数据注解
验证
从全局来看,发现逻辑仅是整个验证的很小的一部分。验证首先需要管理用户友好(本地化)的与验证逻辑相关的错误提示消息;当验证失败时,在把这些错误提示消息呈现给用户界面上,当然还要向用户提供从验证失败中恢复的机制。
数据注解
注解是一种通用机制,可以用来向框架注入元数据,同时,框架不只驱动元数据的验证,还可以在生成显示和编辑模型的HTML标记时使用元数据。通俗的说就是模型上面的特定标识符(具有一定意义和作用)。
验证注解的使用
数据注解定义在一般在命名空间”System.ComponentModel.DataAnnotations”提供了服务器端验证的功能,在模型属性上使用时,框架也支持客户端验证。注解后面都是可以添加错误提示语的,ErrorMessage是每个验证特性中用来设置错误提示消息的参数,比如:
1
2
|
[Required(ErrorMessage = "不能为空" )] public int Age { get; set ; } |
- Required
强调属性是必须的,不可为空。当属性中有一个是null或空时,会引发一个验证错误。
1
2
|
[Required] public int Age { get; set ; } |
- StringLength
要求必须输入名字的长度。参数可以限制最小的。如下:
1
2
|
[StringLength(160,MinimumLength = 3)] public string Name { get; set ; } |
- RegularExpression
正则表达式验证,比如邮箱等需要验证正则的地方。很是方便,这样就减少了服务端的验证。
1
2
|
[RegularExpression(@ "^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+" ,ErrorMessage = "邮箱输入有误,重新输入。" )] public string Email { get; set ; } |
- Range
用来指定数值类型值得最小值和最大值。主要为int类型服务。其余的也可以,需要使用构造函数的重载版本。Type参数来做。
1
2
|
[Range(20,30,ErrorMessage = "年龄不符合要求" )] public int Age { get; set ; } |
1
2
|
[Range(typeof( decimal ), "0.00" , "59.99" )] public decimal Price { get; set ; } |
- Compare
确定两个模型属性拥有一样的值。密码的验证(输入两次,看二者是否一样。),参数为前面模型的值。
1
2
3
4
|
[Required(ErrorMessage = "密码不能为空" )] public string Password { get; set ; } [Compare( "Password" )] public string PasswordPalt { get; set ; } |
- Remote
此特性利用服务器端的回调函数执行客户端的验证逻辑。通俗的说就是这个特性可以直接找到某个控制器的action并且执行其中的方法。
1
2
3
4
5
6
|
/// <summary> /// 验证模型中输入的姓名是否和数据库中重复 /// </summary> /// < returns ></ returns > public JsonResult CheckUserName(string username) { |
1
2
3
|
//数据库中的相关验证 return Json(DateTime.Now.ToString(),JsonRequestBehavior.AllowGet); } |
1
2
|
[Remote( "CheckUserName" , "Admin" )] public string UserName { get; set ; } |
上面控制器操作会利用与UserName属性同名的参数进行验证,同时返回一个javascript object Notaion(json)对象中的布尔类型值(0/1)
- 自定义回复消息占位符
使用{0}占位符,来显示用户的输入,并且形成友好提示。
1
2
|
[Range(20,30,ErrorMessage = "年龄{0}不符合要求" )] public int Age { get; set ; } |
服务端的一些处理(验证与绑定)
ASP.NET MVC的验证特性是由模型绑定器,模型元数据,模型验证器和模型状态组成。
验证和模型绑定
- 操作方法中添加参数
这里有一个隐式地执行模型绑定,一般我们都需要这样写,这样也安全,不会说暴露出来参数。
- 利用UpdateModel或TryUpdateModel方法显式执行绑定
这个实际项目中使用的很少,一般都是通过隐式进行转换的。
1
2
3
4
5
6
7
8
9
10
11
|
[HttpPost,ActionName( "Create" )] public ActionResult CreatePost(Student model) { var model2 = new Student(); UpdateModel(model2); if (TryUpdateModel(model2)) { } return View (model); } |
可以看到参数中的为隐式转换,里面的model2为显式转换。if中的返回的是bool类型。模型绑定器一旦使用新值完成对模型属性的更新,就会利用当前的 模型元数据获得模型的所有验证器。MVC运行时提供了一个验证器(DataAnnotationsModelValidator)来与数据注解一同工作,这个模型验证器会找到所有的验证特性并执行它们包含的验证逻辑,模型绑定器捕获所有失败的验证规则并把它们放入模型状态中。
编程的一个重要原则是不能相信用户的输入
验证与模型状态
模型绑定的副产品是模型状态,也就是我们服务端验证的ModelState,此状态中不仅包含用户的输入,也含有每个相关属性的所有错误(与模型状态本身有关的错误),有错误,ModelState.IsValid就返回false。从而我们就可以进行验证。
1
2
3
4
5
6
7
8
9
10
|
public ActionResult CreatePost(Student model) { var s=ModelState.IsValidField( "UserName" ); var ss=ModelState[ "UserName" ].Errors. Count ; var userName = ModelState[ "UserName" ].Errors[0].ErrorMessage; //获取错误消息 if (ModelState.IsValid) //返回bool类型 { } return View (model); } |
显示和编辑注解
- Display
显示模型属性设置友好的“显示名称”
1
2
3
|
[Display( Name = "姓名" )] [StringLength(160,MinimumLength = 3)] public string Name { get; set ; } |
- ScaffoldColumn
可以隐藏HTML的辅助方法
1
2
|
[ScaffoldColumn( false )] public string Address { get; set ; } |
- DisplayFormat
处理属性各种格式化选项,当属性包含空值,可以提供可选的显示文本。也可以为包含标记的属性关闭HTML编码。还可以运行时指定一个应用于属性值的格式化字符串。
1
2
|
[DisplayFormat(ApplyFormatInEditMode = true ,DataFormatString = "{0:c}" )] public decimal Total { get; set ; } |
- ReadOnly
可以确保默认的模型绑定器不使用请求中的新值来更新属性。
- DataType
运行时提供关于属性的特定用途信息。String类型的属性可应用于很多场合--可以保存e-mail地址,URL或密码。
1
2
3
|
[Required(ErrorMessage = "密码不能为空" )] [DataType(DataType. Password )] public string Password { get; set ; } |
- UIHint
给运行时提供一个模版名称,以备调用模版辅助方法渲染输出时使用。
自定义验证逻辑
- 将验证逻辑封装在自定义的数据注解中。
- 将验证逻辑封装在模型对象中。
把验证逻辑封装在自定义的数据注解中可以轻松地实现在多个模型中重用逻辑。需要在特性内部编写代码以应对不同类型的模型中。
自定义注解
所有的验证注解特性最终都派生自基类ValidationAttribute,它是个抽象类,在System.ComponentMode.DataAnnotation中定义。同样自定义的验证逻辑必须派生自ValidationAttribute的类。且重写IsValid方法(方法里面实现我们相应的逻辑)。
需求:限制用户输入地址中单词数量,设定一个最大值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/// <summary> /// 自定义模型验证 /// 输入数字的单词最大数量 /// </summary> public class MaxWordsAttribute:ValidationAttribute { private readonly int _maxWord; public MaxWordsAttribute( int maxWord) { _maxWord = maxWord; } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { if (value!= null ) { //将输入转换为string类型 var valueAsString = value.ToString(); //使用split( ' ' )空格来分隔输入值,统计生成字符串的数量。对数目比较验证。 if (valueAsString.Split( ' ' ).Length>_maxWord) { return new ValidationResult( "单词超过长度" ); //string类型 } } return ValidationResult.Success; //bool类型 } } |
第一个参数要验证对象中的值。后面进行逻辑的判断。这样做这里的错误提示不能显示到前台。我们需要修改下,使用ValidationAttrubute的ErrorMessage属性来自定义提示错误消息。
修改之后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class MaxWordsAttribute:ValidationAttribute { private readonly int _maxWord; public MaxWordsAttribute( int maxWord) :base( "{0} has too many words" ) { _maxWord = maxWord; } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { if (value!= null ) { //将输入转换为string类型 var valueAsString = value.ToString(); //使用split( ' ' )空格来分隔输入值,统计生成字符串的数量。对数目比较验证。 if (valueAsString.Split( ' ' ).Length>_maxWord) { var errorMessage = FormatErrorMessage(validationContext.DisplayName); return new ValidationResult(errorMessage); } } return ValidationResult.Success; //bool类型 } } |
1
2
|
[MaxWords(5)] public string Address { get; set ; } |
这样效果就会将我们基类中的错误信息显示出来。
我们可以模型基础上添加自定义错误显示。
1
2
|
[MaxWords(5,ErrorMessage = "你输入的单词数超界限,请重新输入。" )] public string Address { get; set ; } |
这里需要注意这里的执行顺序,它是先执行模型上面的验证,接着在到控制器中的action中去的。利用ModelState.IsValid来进行验证。
自验证模型(IValidatableObject)
自验证模型是指一个知道如何验证自身的模型对象,可以让类实现IVaalidatableObject接口来实现对自身的验证。
1
2
3
4
5
6
7
8
9
10
11
12
|
public class Information:IValidatableObject { public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (UserName!= null &&UserName.Split( ' ' ).Length>5) { yield return new ValidationResult( "单词超界限了" ); } } [Display( Name = "用户名" )] public string UserName { get; set ; } } |
其实书上面是在错误返回值中返回的是string类型的数组,如下
1
|
yield return new ValidationResult( "单词超界限了" ,new []{ "UserName" }); |
可以我不知道从那里取出来这个错误消息。只能单独的显示出来。其实把错误消息放在数组中可以进行多模型的验证,从而统一将错误显示出来。
自己的感觉要是需要模型验证,最好还是进行第一种方法,最起码代码看起来干净,第二种给人的感觉是很乱,但是第二种适合比较模型多的场合。
ASP.NET MVC5----数据注解和验证的更多相关文章
- MVC5 数据注解和验证
①利用数据注解进行验证 ②创建自定义的验证逻辑 ③模型元数据注解的用法 ①先创建数据源 1,创建我们的Model Order 2,创建控制器带EF 选择模型为Order 当你运行的时候会报错,需要代 ...
- Asp.net MVC 数据注解与验证
数据注解特性定义在名称空间System.ComponentModel.DataAnnotations中(有些特性定义在其他名称空间中),它们提供了服务器端验证的功能,当在模型的属性上使用这些特性时,框 ...
- 【ASP.NET MVC系列】浅谈数据注解和验证
[ASP.NET MVC系列]浅谈数据注解和验证 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google C ...
- asp.net mvc常用的数据注解和验证以及entity framework数据映射
终于有时间整理一下asp.net mvc 和 entity framework 方面的素材了. 闲话少说,步入正题: 下面是model层的管理员信息表,也是大伙比较常用到的,看看下面的代码大伙应该不会 ...
- MVC学习手册之数据注解与验证
MVC学习手册之数据注解与验证 新建一个MVC5的WEB应用程序,VS2013会自动生成一段代码,以下是Account控制器下Register.cshtml 页面的代码: @model WebAppl ...
- MVC中的数据注解和验证
数据注解和验证 用户输入验证在客户端浏览器中需要执行验证逻辑. 在客户端也需要执行. 注解是一种通用机制, 可以用来向框架注入元数据, 同时, 框架不只驱动元数据的验证, 还可以在生成显示和编辑模型的 ...
- ASP.NET MVC5(四):数据注解和验证
前言 用户输入验证的工作,不仅要在客户端浏览器中执行,还要在服务端执行.主要原因是客户端验证会对输入数据给出即时反馈,提高用户体验:服务器端验证,主要是因为不能完全信任用户提供的数据.ASP.NET ...
- ASP.NET MVC5高级编程 之 数据注解和验证
客户端验证逻辑会对用户向表单输入的数据给出一个即时反馈.而之所以需要服务器端验证,是因为来自网络的信息都是不能被信任的. 当在ASP.NET MVC设计模式上下文中谈论验证时,主要关注的是验证模型的值 ...
- ASP.NET MVC5----常见的数据注解和验证
只要一直走,慢点又何妨. 在使用MVC模式进行开发时,数据注解是经常使用的(模型之上操作),下面是我看书整理的一些常见的用法. 什么是验证,数据注解 验证 从全局来看,发现逻辑仅是整个验证的很小的一部 ...
- 数据注解和验证 – ASP.NET MVC 4 系列
不仅在客户端浏览器中需要执行验证逻辑,在服务器端也需要执行.客户端验证能即时给出一个错误反馈(阻止请求发送至服务器),是时下 Web 应用程序所期望的特性.服务器端验证,主要是因为来自网 ...
随机推荐
- get post 区别【转】
应该是最简洁直接的了???? Get:是以实体的方式得到由请求URI所指定资源的信息,如果请求URI只是一个数据产生过程,那么最终要在响应实体中返回的是处理过程的结果所指向的资源,而不是处理过程的描述 ...
- Linux系统基础认知
什么是操作系统? 操作系统作为接口的示意图: 没有安装操作系统的计算机,通常被称为裸机 如果想在 裸机 上运行自己所编写的程序,就必须用机器语言书写程序 如果计算机上安装了操作系统,就可以在操作系统上 ...
- 小程序在wxml页面格式化类似的2019-02-16T10:54:47.831000时间
其实新建小程序的时候,会有一个util.js文件,这个文件里已经有时间格式化的方法了,可是它却不能再wxml页面调用, 不过wxml页面是支持引入.wxs文件的,我们重新写一个这样子的工具文件就解决了 ...
- es5实现一个class
es5实现一个class https://juejin.im/post/5ac1c5bf518825558949f898#heading-9
- Aliyun搭建svn服务器外网访问报错权限配置失败错误
搭建完后所有的配置如下 [root@iZuf655czz7lmtn8v15tsjZ conf]# pwd /home/SVN/conf [root@iZuf655czz7lmtn8v15tsjZ co ...
- 献给即将35岁的初学者,焦虑 or 出路?
导言:“对抗职场“35 岁焦虑”,也许唯一的方法是比这个瞬息万变的商业社会跑得更快!” 一直以来,都有许多人说“程序员或测试员是个吃青春饭的职业”,甚至还有说“35 岁混不到管理就等于失业”的言论. ...
- 如何用Java8 Stream API找到心仪的女朋友
传统的的Java 集合操作是有些啰嗦的,当我们需要对结合元素进行过滤,排序等操作的时候,通常需要写好几行代码以及定义临时变量. 而Java8 Stream API 可以极大简化这一操作,代码行数少,且 ...
- 远程服务器返回错误:(414)Request-URI Too Large
近期因为疫情原因,一直是在家办公了,也导致了和同事对接接口上出现了很多小问题,这也从侧面反映出我个人对项目的设计不全面. 上面是对接接口时产生的一个问题:远程服务器返回错误:(414)Request- ...
- MySQL Execute Plan--Index Merge特性
Index Merge特性 在MySQL 5.5之前版本中,查询或子查询被限制在一个表只能使用一个索引(回表查询除外). 假设表TB1001上C1和C2列分别有单列索引,如对下面查询: SELECT ...
- opencv —— HoughLines、HoughLinesP 霍夫线变换原理(标准霍夫线变换、多尺度霍夫线变换、累积概率霍夫线变换)及直线检测
霍夫线变换的原理 一条直线在图像二维空间可由两个变量表示,有以下两种情况: ① 在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示. ② 在极坐标系中:可由参数极经和极角(r,θ)表示. 对于霍夫线变 ...