数据注解 是一种可以应用到 类 或者 类成员上用来指定类之间关系的一种 Attribute,它的应用场景比较多,可用来描述 UI 上如何进行数据展示,还可以用来做类属性的规则验证,这篇文章就来讨论为什么 注解 值得你去学习,以及如何在 .NET Core 中使用。
要想运行本篇的例子,需要将 System.ComponentModel.DataAnnotations
引用到项目中。
值得注意的是,Attribute 常用来给 class 或者 property 标注元数据信息,很显然 注解 Atrribute
也是 Attribute 的一种,它的分类大概有以下几种。
从名字上就能看出,主要用在 实体属性上,目的是用来管控 属性值
的有效性。
用来指定数据如何在 UI 上展示。
用来指定类之间的关系。
在 System.ComponentModel.Annotations
命名空间下有如下几个注解类。
现在新建一个 Author 类,代码如下:
public class Author { [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "First Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string FirstName { get; set; } [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "Last Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string LastName { get; set; } [DataType(DataType.PhoneNumber)] [Phone] public string PhoneNumber { get; set; } [DataType(DataType.EmailAddress)] [EmailAddress] public string Email { get; set; } }
下面的代码片段展示了如何给 Author 的属性赋值。
Author author = new Author(); author.FirstName = "Joydip"; author.LastName = ""; author.PhoneNumber = "1234567890"; author.Email = "joydipkanjilal@yahoo.com";
接下来在 Main 方法中去验证这些属性值是否符合验证规则。
ValidationContext context = new ValidationContext(author, null, null); List<ValidationResult> validationResults = new List<ValidationResult>(); bool valid = Validator.TryValidateObject(author, context, validationResults, true); if (!valid) { foreach (ValidationResult validationResult in validationResults) { Console.WriteLine("{0}", validationResult.ErrorMessage); } }
从上面代码可以看出,context 就是 验证规则的上下文,然后调用 Validator.TryValidateObject
去做规则验证,如果有属性不符合 数据注解 的规则,错误信息都会如实的记录到 List<ValidationResult>
集合中。
下面是完整的可供参考的代码。
class Program { static void Main(string[] args) { Author author = new Author(); author.FirstName = "Joydip"; author.LastName = ""; author.PhoneNumber = "1234567890"; author.Email = "joydipkanjilal@yahoo.com"; ValidationContext context = new ValidationContext(author, null, null); List<ValidationResult> validationResults = new List<ValidationResult>(); bool valid = Validator.TryValidateObject(author, context, validationResults, true); if (!valid) { foreach (ValidationResult validationResult in validationResults) { Console.WriteLine("{0}", validationResult.ErrorMessage); } } Console.ReadLine(); } } public class Author { [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "First Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string FirstName { get; set; } [Required(ErrorMessage = "{0} is required")] [StringLength(50, MinimumLength = 3, ErrorMessage = "Last Name should be minimum 3 characters and a maximum of 50 characters")] [DataType(DataType.Text)] public string LastName { get; set; } [DataType(DataType.PhoneNumber)] [Phone] public string PhoneNumber { get; set; } [DataType(DataType.EmailAddress)] [EmailAddress] public string Email { get; set; } }
接下来把程序跑起来,你会在 Console 中看到如下错误信息。
前面都是使用系统内置的,如果你有 自定义验证规则
的需求,那就要重写 ValidationAttribute 类中的 IsValid 方法,如下代码所示:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class IsEmptyAttribute : ValidationAttribute { public override bool IsValid(object value) { var inputValue = value as string; return !string.IsNullOrEmpty(inputValue); } }
然后将这个自定义的 IsEmptyAttribute
标记在 Author 类的 FirstName 和 LastName 属性上,如下代码所示:
[IsEmpty(ErrorMessage = "Should not be null or empty.")] public string FirstName { get; set; } [IsEmpty(ErrorMessage = "Should not be null or empty.")] public string LastName { get; set; }
数据注解 最初是在 .NET 3.5 中作为 System.ComponentModel.DataAnnotations
的一部分被引入的,从那时起,它就越来越流行了,你可以直接在属性上加 数据注解 避免在项目各处中都有对 Author 实体类的验证逻辑,这种也太麻烦了,不是吗?