第十节:数据批注(DataAnnotationModel)和自定义验证(包括Model级别的验证)
一. 简介
写完上一个章节MVC中的常用特性,迫不及待将该系列补全,该章节主要介绍数据批注(也叫:注解)。
一听【数据批注】,好高大上的名字,但仔细一看,它们其实是【System.ComponentModel.DataAnnotations】程序集下的一些特性类,O(∩_∩)O哈哈~,既然是特性,就符合特性的所有特征,只不过这些特性是作用于“属性”上的。
再一看【System.ComponentModel.DataAnnotations】这个命名空间,有点眼熟,与之前EF中的一篇文章【EF的CodeFirst模式通过DataAnnotations修改默认协定】中的一类操作来源于同一个命名空间下。
所以综上所述:该命名空间下的特性,在EF中可以用来映射生成数据库中的表字段,在日常开发中也可以用于做类中属性的限制和验证。
原理:均继承了ValidationAttribute特性,通过覆写IsValide方法进行校验。
适用场景:很多项目需要客户端和服务器端进行双重格式验证,使之更加安全,这时服务器端就可以使用数据批注了来进行校验了。
以Required特性为例,查看一下源码:

二. 常用的数据批注
这里总结一下【System.ComponentModel.DataAnnotations】命名空间下常用的数据批注,即特性。
① Key :声明主键
② Required:非空声明
③ MinLength和MaxLength:设置string类型的最大长度和最小长度,数据库的对应nvarchar
④ StringLength:设置string类型的长度,数据库对应nvarchar
⑤ Compare:新老密码对比
⑥ RegularExpression:正则的匹配
⑦ Phone:验证手机号码
⑧ Range:验证范围
⑨ Timestamp:将byte[]类型设置为timestamp类型
⑩ ConcurrencyCheck:并发检查,执行update操作时,会检查并发性(乐观锁) (在后面并发章节着重介绍Timestamp和ConcurrencyCheck)
另外还有一些不是很常用的,如:
① DisplayName:声明属性的名称
② Remote:远程验证,需要JQuery插件的支持 (这里不做测试等待补充 参考: https://www.cnblogs.com/JustRun1983/p/3505151.html)
下面补充一下该命名空间反射源码,可以自行查找需要的批注:


代码测试:
(1). 实体类,在其属性上添加数据标注
/// <summary>
/// 用户信息类 ,用于测试框架本身提供的数据批注
/// </summary>
public class UserInfor
{
[Required]
public string id { get; set; } [StringLength()]
public string userName { get; set; } [MaxLength()]
public string userMsg { get; set; } [Range(, )]
public int userAge { get; set; } [RegularExpression("[a-d]")] //a-d中的一个
public string userMsg3 { get; set; } [Phone]
public string userPhone { get; set; } public string userOldPwd { get; set; } [Compare("userOldPwd")] //比较和userOldPwd的值是否相等
public string userNewPwd { get; set; } }
(2). 前端代码
//1. 测试数据批注
$("#btn1").click(function () {
$.ajax({
type: "Post",
url: "TestDataAnnotationModel",
data: {
"id":"123",
"userName": "mr12",
"userMsg": "ypf1234",
"userAge": 6,
"userMsg3": "a",
"userPhone": "15764222366",
"userOldPwd": "123456",
"userNewPwd":"123456" },
success: function (data) {
if (data == "ok") {
alert("测试通过");
}
if (data == "error") {
alert("测试未通过");
}
}
});
});
(3). 服务器端代码
public ActionResult TestDataAnnotationModel(UserInfor user)
{
//通过该方法进行验证
var isValidate = ModelState.IsValid; if (isValidate)
{
return Content("ok");
}
return Content("error");
}
三. 自定义数据批注
思路:通过上面的批注源码可知,均为自定义类继承:ValidationAttribute,覆写IsValid方法
需求:这里我们自定义一个批注,要求不为空,且长度区间为6-12位
使用方法同样为:action中通过实体接收,通过ModelState.IsValid的值为true或false来判断验证是否通过
代码测试:
(1). 实体类和自定义批注
/// <summary>
/// 角色类,用于测试自定义业务的数据批注
/// </summary>
public class RoleInfor
{ public string id { get; set; } [myOwnCheck]
public string roleName { get; set; }
} /// <summary>
/// 自定义数据批注,要求非空且长度为6-12位
/// </summary>
public class myOwnCheckAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value != null && value.ToString().Length > && value.ToString().Length < )
{
return true;
}
return false;
}
}
(2). 前端代码
//2. 测试自定义业务逻辑的验证
$("#btn2").click(function () {
$.ajax({
type: "Post",
url: "TestMyOwnCheck",
data: {
"id": "",
"roleName": "mr12345"
},
success: function (data) {
if (data == "ok") {
alert("测试通过");
}
if (data == "error") {
alert("测试未通过");
}
}
});
});
(3). 服务器端代码
public ActionResult TestDataAnnotationModel(UserInfor user)
{
//通过该方法进行验证
var isValidate = ModelState.IsValid; if (isValidate)
{
return Content("ok");
}
return Content("error");
}
四. Model级别的验证扩展
实现IValidaableObjec接口,实现Validate方法。(了解即可)
public class CarInfor: IValidatableObject
{
public string id { get; set; } public string carName { get; set; } public int carAge { get; set; } IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
if (carAge % == )
{
var result = new ValidationResult("车龄验证不通过", new string[] { "carAge" }); yield return result;
}
}
}

第十节:数据批注(DataAnnotationModel)和自定义验证(包括Model级别的验证)的更多相关文章
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobackupex/Xtrabackup 第四十节课
centos shell编程6一些工作中实践脚本 nagios监控脚本 自定义zabbix脚本 mysql备份脚本 zabbix错误日志 直接送给bc做计算 gzip innobacku ...
- 第三百一十四节,Django框架,自定义分页
第三百一十四节,Django框架,自定义分页 自定义分页模块 #!/usr/bin/env python #coding:utf-8 from django.utils.safestring impo ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第十节
原文链接 第十节:CUDPP, 强大的数据平行CUDA库Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多 ...
- 第三百八十节,Django+Xadmin打造上线标准的在线教育平台—将所有app下的models数据库表注册到xadmin后台管理
第三百八十节,Django+Xadmin打造上线标准的在线教育平台—将所有app下的models数据库表注册到xadmin后台管理 将一个app下的models数据库表注册到xadmin后台管理 重点 ...
- 第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页
第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页 逻辑处理函数 计算搜索耗时 在开始搜索前:start_time ...
- 第三百一十节,Django框架,模板语言
第三百一十节,Django框架,模板语言 模板语言就是可以将动态数据在html模板渲染的语言 一.接收值渲染 locals()函数,写在请求响应render()函数里,可以将逻辑处理函数里的变量传到h ...
- centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课
centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 ...
- 第十节:详细讲解一下Java多线程,随机文件
前言 大家好,给大家带来第十节:详细讲解一下Java多线程,随机文件的概述,希望你们喜欢 多线程的概念 线程的生命周期 多线程程序的设计 多线程的概念 多线程的概念:程序是静态的,进程是动态的.多进程 ...
随机推荐
- 在搭建tesseract-OCR环境中遇到问题和反省
Tesseract,一款由HP实验室开发由Google维护的开源OCR(Optical Character Recognition , 光学字符识别)引擎,特点是开源,免费,支持多语言,多平台. 在搭 ...
- HybridStart发布v1.0测试版
HybridStart是一款多webview模式的混合应用前端开发框架,本来只是作者自用的一套混合应用开发模板,为了进一步提高混合应用开发效率,近期着重在框架高通用性和易用性方面做了较大改进,比如将U ...
- 如何用Nginx解决前端跨域问题?
前言 在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调. 最简单的解决方法,就是把浏览器设为忽略安全问题,设置--di ...
- SQL数据库一些系统语法含义
昨天在数据库中建立数据表的时候要求显示的添加一些系统语法规则,对于这些设置不知道都是什么含义,这次记录下来供以后学习. (1)SET ANSI_NULLS ON语句 T-SQL支持在与空值进行比较时, ...
- springboot中,页面访问不到静态资源
例一,静态资源放在默认的目录,如:resources/static或resources/templates 访问静态资源的时候,路径不应带上默认目录,因为springboot默认从这些目录下开始加载, ...
- docker其他参考资料
https://yeasy.gitbooks.io/docker_practice/image/build.html https://blog.csdn.net/weixin_42596342/art ...
- SQL Server百万级大数据量删除
删除一个表中的部分数据,数据量百万级. 一般delete from 表 delete from 表名 where 条件: 此操作可能导致,删除操作执行的时间长:日志文件急速增长: 针对此情况处理 de ...
- MongoDB install
下载地址1:https://www.mongodb.org/dl/linux下载地址2:https://www.mongodb.com/download-center/community关于Mongo ...
- 3-STM32带你入坑系列(自己封装点亮一个灯的库--Keil)
2-STM32带你入坑系列(点亮一个灯--Keil) 首先建一个stm32f103x.h的文件,然后 #include "stm32f103x.h" 还记得上一节 现在呢就是做一个 ...
- 【学习总结】GirlsInAI ML-diary day-12-for循环
[学习总结]GirlsInAI ML-diary 总 原博github链接-day12 认识for循环执行 ps: range()函数 python range() 函数可创建一个整数列表,一般用在 ...