.net 使用validator做数据校验

概述

在把用户输入的数据存储到数据库之前一般都要对数据做服务端校验,于是想到了.net自带的数据校验框架validator。本文对validator的使用方法进行介绍,并分析下校验的的原理。

使用validator校验数据

首先我们创建一个需要校验的实体类代码如下:

[Table("apple")]
    public class Apple
    {
        public Guid Id {get;set;}

        [MaxLength(3,ErrorMessage="名称长度不能超过3个")]
        public string Name {get;set;}

        public string Comment {get;set;}

        public virtual ICollection<Banana> Bananas { get; set; }

    }

我们在Name属性添加了一个校验元数据MaxLength。

然后使用下面的代码对数据进行校验:

  Apple apple = new Apple(){Name = "tes你"};
  string strLength = "";

  List<ValidationResult> results = new List<ValidationResult>();
            ValidationContext validateContext = new ValidationContext(apple);

            if (Validator.TryValidateObject(apple, validateContext, results, true))
            {
                strLength = "it is ok!";
            }

校验失败会在 results中出现错误信息。

自定义校验方法

例如上面的例子,如果我们希望是按字节数来校验数据,而不是字符串长度。我们就需要对校验方法进行扩张并自定义实现校验方法了。扩展校验方法的代码如下:

public class NewMaxLengthAttribute : MaxLengthAttribute
    {
        public NewMaxLengthAttribute()
            : base()
        { }

        public NewMaxLengthAttribute(int length)
            : base(length)
        { }

        public override bool IsValid(object value)
        {
            if (value != null && value is string  )
            {
                int byteLength = System.Text.Encoding.Default.GetByteCount(value.ToString());
                if (  byteLength > base.Length )
                { 
                    return false;
                } 
            } 
            return true; 
        }
    }

对MaxLengthAttribute进行继承,并重载校验方法IsValid即可。

validator实现原理分析

模拟validator代码如下:

          Apple apple = new Apple(){Name = "tes你"};         
         Type typeForTest = apple.GetType(); foreach (PropertyInfo ai in typeForTest.GetProperties()) { var test = ai.GetCustomAttribute(typeof(MaxLengthAttribute), false) as MaxLengthAttribute; var aiType = ai.GetType(); if (test != null && ai.PropertyType.Name.Equals("String")) { var length = test.Length; var propertyValue = ai.GetValue(apple).ToString(); int byteLength = System.Text.Encoding.Default.GetByteCount(propertyValue); if (length >= byteLength) { res+= " OK"; } else {
                res+= "数据不合理";
              }
            }
          }

利用反射读取实体的属性上定义的元数据信息,然后对数据进行校验。