您的位置:首页 > 编程语言 > ASP

深入ASP.NET MVC Model验证-使用.NET验证特性类指定Mode验证规则

2018-03-06 13:11 651 查看
上一篇文章也有介绍使用验证特性类指定Mode验证规则,但是介绍的不是很详细,下面详细深入谈谈如何使用.NET内置验证特性类指定Mode验证规则及自定义符合自己的业务规则的验证特性类的方法。

一、使用内置的.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重要作用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: