现在看asp.net MVC5自学已经到了第六章:数据注解与验证。

话得从以前看MVC music store(音乐商店项目)的源码说起,

最初看music store源码完全就是一脸懵逼,整个程序,找了半天,只看到控制器有少许逻辑代码,例如编辑专辑的视图里面,用户输入的title到底符不符合规范, VIEW里面即无相关验证的JS代码,又没有进行后台的数据判断。

 1 @using (Html.BeginForm()) {
 2     @Html.ValidationSummary(true)
 3     <fieldset>
 4         <legend>Album</legend>
 5
 6         @Html.HiddenFor(model => model.AlbumId)
 7
 8         <div class="editor-label">
 9             @Html.LabelFor(model => model.GenreId, "Genre")
10         </div>
11         <div class="editor-field">
12             @Html.DropDownList("GenreId", String.Empty)
13             @Html.ValidationMessageFor(model => model.GenreId)
14         </div>
15
16         <div class="editor-label">
17             @Html.LabelFor(model => model.ArtistId, "Artist")
18         </div>
19         <div class="editor-field">
20             @Html.DropDownList("ArtistId", String.Empty)
21             @Html.ValidationMessageFor(model => model.ArtistId)
22         </div>
23
24         <div class="editor-label">
25             @Html.LabelFor(model => model.Title)
26         </div>
27         <div class="editor-field">
28             @Html.EditorFor(model => model.Title)
29             @Html.ValidationMessageFor(model => model.Title)
30         </div>
31
32         <div class="editor-label">
33             @Html.LabelFor(model => model.Price)
34         </div>
35         <div class="editor-field">
36             @Html.EditorFor(model => model.Price)
37             @Html.ValidationMessageFor(model => model.Price)
38         </div>
39
40         <div class="editor-label">
41             @Html.LabelFor(model => model.AlbumArtUrl)
42         </div>
43         <div class="editor-field">
44             @Html.EditorFor(model => model.AlbumArtUrl)
45             @Html.ValidationMessageFor(model => model.AlbumArtUrl)
46         </div>
47
48         <p>
49             <input type="submit" value="Save" />
50         </p>
51     </fieldset>
52 }

音乐商店编辑专辑的视图

程序到底是怎么完成数据验证呢?

今天看了这一章对数据验证就有了大概的了解了。

===========================================================

前提:C# Attribute特性和反射

  翻到专辑的Model(实体类)里,我们看到Album类的定义是这样的。

public class Album{[ScaffoldColumn(false)]public int AlbumId { get; set; }[DisplayName("Genre")]public int GenreId { get; set; }[DisplayName("Artist")]public int ArtistId { get; set; }[Required(ErrorMessage = "An Album Title is required")][StringLength(160)]public string Title { get; set; }[Required(ErrorMessage = "Price is required")][Range(0.01, 100.00,ErrorMessage = "Price must be between 0.01 and 100.00")]public decimal Price { get; set; }[DisplayName("Album Art URL")][StringLength(1024)]public string AlbumArtUrl { get; set; }public virtual Genre Genre { get; set; }public virtual Artist Artist { get; set; }public virtual List<OrderDetail> OrderDetails { get; set; }

  原来,模型类里面大量采用attribute特性

  关于Attribute特性我原先一直没有搞懂它到底是怎么运作的。写个方括号,括起来一个类,为什么就能让我的属性、方法、类有了限制?

  下面我首先简介一下Attribute特性的一些基本要点:

    1、特性类其实就是一个从Attribute基类继承而来的类。

    2、自定义Attribute只能在反射时生效。

  等等,第二个基本要点中:反射。它的定义就是反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

  这也就是说,利用反射,我们可以得到一个类里面所有的特性。似乎我可以猜测到一点特性的运行原理了:我们可以在特性类中做文章,在反射时,获取了被标注的类的所有特性,运行这个这些特性的某些方法或者属性,就可以对这个被标注的类进行验证或者限制。

  

验证的运行原理:利用特性来进行验证。

  

 [StringLength(160)]public string Title { get; set; }

  在上面一个属性中,有一个StringLengt(160)的特性,MVC书上称他为验证。

  // 摘要: //     指定数据字段中允许的最小和最大字符长度。[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]public class StringLengthAttribute : ValidationAttribute{// 摘要: //     使用指定的最大长度初始化 System.ComponentModel.DataAnnotations.StringLengthAttribute//     类的新实例。//// 参数: //   maximumLength://     字符串的最大长度。public StringLengthAttribute(int maximumLength);// 摘要: //     获取或设置字符串的最大长度。//// 返回结果: //     字符串的最大长度。public int MaximumLength { get; }//// 摘要: //     获取或设置字符串的最小长度。//// 返回结果: //     字符串的最小长度。public int MinimumLength { get; set; }// 摘要: //     对指定的错误消息应用格式设置。//// 参数: //   name://     要进行格式设置的错误消息。//// 返回结果: //     带有格式的错误消息。//// 异常: //   System.ArgumentOutOfRangeException://     maximumLength 为负数。- 或 -maximumLength 小于 minimumLength。public override string FormatErrorMessage(string name);//// 摘要: //     确定指定的对象是否有效。//// 参数: //   value://     要验证的对象。//// 返回结果: //     如果指定的对象有效,则为 true;否则为 false。//// 异常: //   System.ArgumentOutOfRangeException://     maximumLength 为负数。- 或 -maximumLength 小于 System.ComponentModel.DataAnnotations.StringLengthAttribute.MinimumLength。public override bool IsValid(object value);}

  翻开它的元数据我们可以看到,它其实就是一个微软提供的自定义特性它继承自ValidationAttribute,ValidationAttribute又继承自Attribute

  通过元数据我们可以看到,它其中有一个重写的bool IsVlid(object value) 方法,它就是用来判断被标注的对象是否验证成功的入口。

  实际上,翻开ValidationAttribute的元数据,IsValid方法提供了很多重载版,验证特性要成功,最少都要重写一个方法,在方法里进行逻辑判断,确定是否验证成功。

==========================================================================================

MVC特性验证的原理

  以下是书上的解释:

  1、asp.net mvc框架可以自动绑定模型,如果控制器带了参数,MVC运行时会隐式地根据参数类型的标识符,从GET或者POST来的键值对里面找相同名字的键填充值。当然,控制器不带参数,也可以通过tryupdatemodel,或者updatemodel两个方法来完成模型绑定。

  2、在模型绑定之后,下一步就是反射被绑定后的模型,反射获取这个模型对象的验证特性,也就是例如[StringLength(160)]这些特性。

  3、得到所有验证特性之后,就调用这些验证特性类的isvalid方法,对被绑定属性进行验证。

  4、MVC运行时会捕捉所有isvalid方法返回值为false的验证规则,并把他们加入到ModelState中。

  5、如果ModelState中有任何一个验证的失败信息,ModelState的isValid属性都将设定为False。

  6、在前端视图中,我们就可以调用一个辅助方法: @Html.ValidationMessageFor(model => model.GenreId),去ModelState中找这个错误,辅助方法会自动根据ModelState中的错误信息拼装包含你传入的数据抛出的验证错误的HTML。

  如此一来,通过这6个步骤,仅仅依靠特性就能对数据进行验证。大大地提高了编码效率,减少了编码量

 

转载于:https://www.cnblogs.com/bibibibi/p/6481690.html

2017年2月28日-----------乱码新手自学.net 之特性与验证相关推荐

  1. 2017年2月28日 星期二 --出埃及记 Exodus 23:18

    2017年2月28日 星期二 --出埃及记 Exodus 23:18 "Do not offer the blood of a sacrifice to me along with anyt ...

  2. 【面经】陌陌-2017年8月28日,散招实习生

    现在坐着公交车回学校,刚面试完脑仁炸疼,实在无力复习,写篇面经权当放松了.陌陌面试只问了项目和源码,最后据HR说前面两面的面试官评价都不错,向人力总监确认后可能会发offer,不过随便发不发吧,竟然还 ...

  3. 手机号码段简介以及最新手机号段归属地数据库(2017年6月28日)

    什么是手机号码段? 我国使用的手机号码为11位,其中各段有不同的编码方向:前3位-网络识别号:第4-7位-地区编码:第8-11位-用户号码.号码也就是所谓的MDN号码,即本网移动用户作被叫时,主叫用户 ...

  4. 2017年4月28日 星期五 --出埃及记 Exodus 25:26

    2017年4月28日 星期五 --出埃及记 Exodus 25:26 Make four gold rings for the table and fasten them to the four co ...

  5. 老男孩教育每日一题-2017年4月28日- MySQL主从复制常见故障及解决方法?

    MySQL主从复制常见故障及解决方法? 1.1.1故障1:从库数据与主库冲突 show slave status; 报错:且show slave status\G Slave_I/O_Running: ...

  6. 2017年6月28日 python爬虫学习

    1.写入csv文件 2.lxml的用法 3.自定义字典类的方法 4.bytes解码得到str,str编码得到bytes 5.json 1 import csv import lxml.html cla ...

  7. 信支付jsapi(java版)【1】微信商户号mchid哪里找 2017年02月28日 08:45:33

    我们在开发微信支付功能的时候首先必须确定两个非常重要的参数,就是商户号mchid和商户秘钥key,那么这两个参数在哪里获取呢,请仔细阅读下面的查询方法. 一.微信支付商户号mchid的查找 1.1.登 ...

  8. 【2017 数据技术嘉年华】10月28日广州站即将华丽来袭!

    还有 8 天 我们就要 到达广州站 啦 在各位业界同仁的支持下,ACOUG 已经成功举办六届千人规模的 Oracle 技术嘉年华.今年,秉承"云 • 数据 • 智能 - 数聚价值 智胜未来& ...

  9. 数据技术嘉年华专列10月28日抵达广州,请做好接站准备

    第七届数据技术嘉年华 - 广州站 会议通知 主题:云 • 数据 • 智能 - 数聚价值 智胜未来 时间:2017年10月28日(周六) 地点:广州市广武酒店(天河区天河路 603 号) 人员:Dear ...

  10. 航海世纪服务器维护中,航海世纪2月28日例行维护公告

    为保证服务器的稳定与服务质量,航海世纪所有服务器将于2017年2月28日9:00停机,进行例行维护工作,维护时间为9:00至12:00,如果在维护期间无法完成维护相关事宜,开机时间将继续顺延,请各位玩 ...

最新文章

  1. Kafka-0.10.0.0 集群高可靠实验
  2. android开发年总结
  3. npm更新模块并同步到package.json中
  4. keras保存模型_onnx+tensorrt部署keras模型
  5. mysql数据库修改数据库名称_MySQL数据库之MySQL 修改数据库名称的一个新奇方法...
  6. NumPy Cookbook 带注释源码 十、Scikit 中的乐趣
  7. 数字图像恢复matlab结论,matlab模糊图像恢复数字图像处理
  8. Linux系统下如何配置SSH?如何开启SSH?
  9. cisco Router专线路由器配置
  10. ubuntu LVM
  11. cad2012打开后闪退_windows7打不开CAD2012出现闪退的处理方法
  12. 微信小程序 定位获取开发模式好的 但是真机就失败了
  13. latex 插入bibtex 的文献。在参考文献上方多了一行序号,解决办法参考
  14. python 新浪邮箱发送邮件
  15. sap增加税码注意事项
  16. [译]带你揭开Kotlin中属性代理和懒加载语法糖衣
  17. android type c 耳机检测,USB Type-C 的新音频标准将帮助 Android 设备去掉 3.5mm 耳机孔...
  18. 2020年的1024程序员节(娱乐小文章)
  19. steam上c语言的游戏,【图片】在steam吧你甚至可以讨论c语言_steam吧_百度贴吧
  20. 多位数的各位数数字提取方法

热门文章

  1. kubernetes【工具】kind【1】入门实践
  2. android自定义素材拼图,众望所归 美图秀秀Android拼图隆重上线
  3. mybatis报错:org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC
  4. 【学会了学会了】Flink官网翻译——Flink集群部署概览
  5. HTML制作搞笑照片,美图秀秀怎么制作搞笑的GIF表情 搞笑的GIF表情在怎么制作
  6. 数据铁笼-郑州Android项目ViewPager刷新问题
  7. 中国MES市场主流厂商及产品分析
  8. 国外最流行的Bootstrap后台管理模板
  9. Oracle rman中restore和recover的区别
  10. JPA之Specification复杂条件查询