深入ASP.NET MVC Model验证-使用.NET验证特性类指定Mode验证规则
2018-03-06 13:11
651 查看
上一篇文章也有介绍使用验证特性类指定Mode验证规则,但是介绍的不是很详细,下面详细深入谈谈如何使用.NET内置验证特性类指定Mode验证规则及自定义符合自己的业务规则的验证特性类的方法。
CreditCardAttribute 指定数据字段值是信用卡号码。
CustomValidationAttribute 指定自定义的验证方法来验证属性或类的实例。
DataTypeAttribute 指定要与数据字段关联的附加类型的名称。
DisplayAttribute 提供一个通用特性,使您可以为实体分部类的类型和成员指定可本地化的字符串。
EmailAddressAttribute 确认一电子邮件地址。
MaxLengthAttribute 指定属性中允许的数组或字符串数据的最大长度。
MinLengthAttribute 指定属性中允许的数组或字符串数据的最小长度。
PhoneAttribute 使用电话号码的正则表达式,指定数据字段值是一个格式正确的电话号码。
RangeAttribute 指定数据字段值的数值范围约束。
RegularExpressionAttribute 指定 ASP.NET 动态数据中的数据字段值必须与指定的正则表达式匹配。
RequiredAttribute 指定需要数据字段值。
UrlAttribute 提供 URL 验证。
下面我们看看怎么使用这些内置的验证特性类来定义我们Model类,并让它字段必须满足一定的规则:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.linq;
using System.Web;
namespace mvcModelBindingDemo.Models
{
public class Appointment
{
[Required(ErrorMessage="ClientName为必填项目")]
public string ClientName { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
上面规定即为:CientName为必填,Date为日期类型。
2、1、自定义一个属性验证特性类
下面我们定义FutureDateAttribute来验证一个字段必须为日期且其值必须大于当前时间。
using System;
using System.ComponentModel.DataAnnotations;
namespace MVCModelBindingDemo.Infrastructure {
public class FutureDateAttribute : RequiredAttribute {
public override bool IsValid(object value) {
return base.IsValid(value) && ((DateTime)value) > DateTime.Now;
}
}
}
我们自定义的这个特性类FutureDateAttribute是继承于内置的.NET验证特性类RequiredAtrribute并重写了其方法IsValid,使其不仅要验证它为必填项且是未来的某个日期。
定义好了这个特性类,使用和内置的验证特性类没有区别。如下:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace MVCModelBindingDemo.Models
{
public class Appointment
{
[Required(ErrorMessage="ClientName为必填项目")]
public string ClientName { get; set; }
[DataType(DataType.Date)]
[FutureDate(ErrorMessage="请输入一个未来的日期")]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
2.2、自定义一个Model验证特性类
除了定义一个针对某个字段进行验证的的特性类,我们还可以自定义一个Model验证特性类,在里面依次进行验证每个字段。下面定义一个Model验证特性类NoJoeOnMondaysAttribute用来验证,当ClientName为Joe时,Date不能为星期天。
using System;
using System.ComponentModel.DataAnnotations;
using MVCModelBindingDemo.Models;
namespace ModelValidation.Infrastructure {
public class NoJoeOnMondaysAttribute : ValidationAttribute {
public NoJoeOnMondaysAttribute() {
ErrorMessage = "Joe cannot book appointments on Mondays";
}
public override bool IsValid(object value) {
Appointment app = value as Appointment;
if (app == null || string.IsNullOrEmpty(app.ClientName) ||
app.Date == null) {
//当没model为空或者没有ClientName为空或Date为null直接返回true
return true;
} else {
return !(app.ClientName == "Joe" &&
app.Date.DayOfWeek == DayOfWeek.Monday);
}
}
}
}
在Model中定义使用这个Model验证特性类:
using System;
using System.ComponentModel.DataAnnotations;
using MVCModelBindingDemo.Infrastructure;
namespace MVCModelBindingDemo.Models
{
[NoJoeOnMondays]
public class Appointment
{
[Required(ErrorMessage="ClientName为必填项目")]
public string ClientName { get; set; }
[DataType(DataType.Date)]
[FutureDate(ErrorMessage="请输入一个未来的日期")]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using MVCModelBindingDemo.Infrastructure;
namespace MVCModelBindingDemo.Models {
public class Appointment : IValidatableObject {
public string ClientName { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext
validationContext) {
List<ValidationResult> errors = new List<ValidationResult>();
if (string.IsNullOrEmpty(ClientName)) {
errors.Add(new ValidationResult("Please enter your name"));
}
if (DateTime.Now > Date) {
errors.Add(new ValidationResult("Please enter a date in the future"));
}
if (errors.Count == 0 && ClientName == "Joe"
&& Date.DayOfWeek == DayOfWeek.Monday) {
errors.Add(
new ValidationResult("Joe cannot book appointments on Mondays"));
}
if (!TermsAccepted) {
errors.Add(new ValidationResult("You must accept the terms"));
}
return errors;
}
}
}
从上面我们可以看到在定义Model类Appointment的时使用了接口IValidatableObject,而要在Appoint类中实现一个接口中的方法Validate,返回一个IEnumerable<ValidationResult>类型的集合。
当MVC框架的model binder为我们model的每个属性赋好值之后,这个Validate方法将会被调用。可能有的人不喜欢把验证逻辑放在Model中,因为他们这样违反了Model的单一职责性,但是我觉得在MVC架构中这样把验证逻辑放在model中其实也不失一种不错的选择,这样充分的发挥了MVC中三大重要元素这一的Model重要作用。
一、使用内置的.NET验证特性类
在程序集 System.ComponentModel.DataAnnotations.dll, v4.0.0.0中为我们定义很多有用的验证特性类。最常用类如下:CompareAttribute 提供比较两个属性的属性。CreditCardAttribute 指定数据字段值是信用卡号码。
CustomValidationAttribute 指定自定义的验证方法来验证属性或类的实例。
DataTypeAttribute 指定要与数据字段关联的附加类型的名称。
DisplayAttribute 提供一个通用特性,使您可以为实体分部类的类型和成员指定可本地化的字符串。
EmailAddressAttribute 确认一电子邮件地址。
MaxLengthAttribute 指定属性中允许的数组或字符串数据的最大长度。
MinLengthAttribute 指定属性中允许的数组或字符串数据的最小长度。
PhoneAttribute 使用电话号码的正则表达式,指定数据字段值是一个格式正确的电话号码。
RangeAttribute 指定数据字段值的数值范围约束。
RegularExpressionAttribute 指定 ASP.NET 动态数据中的数据字段值必须与指定的正则表达式匹配。
RequiredAttribute 指定需要数据字段值。
UrlAttribute 提供 URL 验证。
下面我们看看怎么使用这些内置的验证特性类来定义我们Model类,并让它字段必须满足一定的规则:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.linq;
using System.Web;
namespace mvcModelBindingDemo.Models
{
public class Appointment
{
[Required(ErrorMessage="ClientName为必填项目")]
public string ClientName { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
上面规定即为:CientName为必填,Date为日期类型。
二、扩展内置的.NET验证特性类
2、1、自定义一个属性验证特性类
下面我们定义FutureDateAttribute来验证一个字段必须为日期且其值必须大于当前时间。using System;
using System.ComponentModel.DataAnnotations;
namespace MVCModelBindingDemo.Infrastructure {
public class FutureDateAttribute : RequiredAttribute {
public override bool IsValid(object value) {
return base.IsValid(value) && ((DateTime)value) > DateTime.Now;
}
}
}
我们自定义的这个特性类FutureDateAttribute是继承于内置的.NET验证特性类RequiredAtrribute并重写了其方法IsValid,使其不仅要验证它为必填项且是未来的某个日期。
定义好了这个特性类,使用和内置的验证特性类没有区别。如下:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace MVCModelBindingDemo.Models
{
public class Appointment
{
[Required(ErrorMessage="ClientName为必填项目")]
public string ClientName { get; set; }
[DataType(DataType.Date)]
[FutureDate(ErrorMessage="请输入一个未来的日期")]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
2.2、自定义一个Model验证特性类
除了定义一个针对某个字段进行验证的的特性类,我们还可以自定义一个Model验证特性类,在里面依次进行验证每个字段。下面定义一个Model验证特性类NoJoeOnMondaysAttribute用来验证,当ClientName为Joe时,Date不能为星期天。
using System;
using System.ComponentModel.DataAnnotations;
using MVCModelBindingDemo.Models;
namespace ModelValidation.Infrastructure {
public class NoJoeOnMondaysAttribute : ValidationAttribute {
public NoJoeOnMondaysAttribute() {
ErrorMessage = "Joe cannot book appointments on Mondays";
}
public override bool IsValid(object value) {
Appointment app = value as Appointment;
if (app == null || string.IsNullOrEmpty(app.ClientName) ||
app.Date == null) {
//当没model为空或者没有ClientName为空或Date为null直接返回true
return true;
} else {
return !(app.ClientName == "Joe" &&
app.Date.DayOfWeek == DayOfWeek.Monday);
}
}
}
}
在Model中定义使用这个Model验证特性类:
using System;
using System.ComponentModel.DataAnnotations;
using MVCModelBindingDemo.Infrastructure;
namespace MVCModelBindingDemo.Models
{
[NoJoeOnMondays]
public class Appointment
{
[Required(ErrorMessage="ClientName为必填项目")]
public string ClientName { get; set; }
[DataType(DataType.Date)]
[FutureDate(ErrorMessage="请输入一个未来的日期")]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
}
}
三、MVC 中定义自验证Model
什么是自验证Model呢?简单的说就是Model验证的逻辑放在Model类中,如下面的代码:using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using MVCModelBindingDemo.Infrastructure;
namespace MVCModelBindingDemo.Models {
public class Appointment : IValidatableObject {
public string ClientName { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext
validationContext) {
List<ValidationResult> errors = new List<ValidationResult>();
if (string.IsNullOrEmpty(ClientName)) {
errors.Add(new ValidationResult("Please enter your name"));
}
if (DateTime.Now > Date) {
errors.Add(new ValidationResult("Please enter a date in the future"));
}
if (errors.Count == 0 && ClientName == "Joe"
&& Date.DayOfWeek == DayOfWeek.Monday) {
errors.Add(
new ValidationResult("Joe cannot book appointments on Mondays"));
}
if (!TermsAccepted) {
errors.Add(new ValidationResult("You must accept the terms"));
}
return errors;
}
}
}
从上面我们可以看到在定义Model类Appointment的时使用了接口IValidatableObject,而要在Appoint类中实现一个接口中的方法Validate,返回一个IEnumerable<ValidationResult>类型的集合。
当MVC框架的model binder为我们model的每个属性赋好值之后,这个Validate方法将会被调用。可能有的人不喜欢把验证逻辑放在Model中,因为他们这样违反了Model的单一职责性,但是我觉得在MVC架构中这样把验证逻辑放在model中其实也不失一种不错的选择,这样充分的发挥了MVC中三大重要元素这一的Model重要作用。
相关文章推荐
- ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则
- ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则
- asp.net MVC 中使用dataannotation验证Model
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
- 【原创】Asp.Net MVC 学习笔记之-使用Model验证
- Asp.net mvc + .net ef database first 或 model first 时如何添加验证特性
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider
- Asp.net mvc + .net ef database first 或 model first 时如何添加验证特性
- ASP.NET MVC 使用Remote特性实现远程属性验证
- Asp.net MVC验证那些事(1)-- 介绍和验证规则使用
- ASP.NET MVC基于标注特性的Model验证:ValidationAttribute
- .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(三)
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator
- Asp.net MVC验证那些事(1)-- 介绍和验证规则使用
- Asp.net MVC验证哪些事(2)-- 验证规则总结以及使用
- Asp.net MVC验证哪些事(2)-- 验证规则总结以及使用
- ASP.NET MVC基于标注特性的Model验证:ValidationAttribute
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
- Asp.net MVC验证那些事(1)-- 介绍和验证规则使用
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator