WebApi开发爬坑记之·重写ValidationAttribute自定义DateTimeCompareAttribute

   ValidationAttribute验证特性一般用来验证数据的格式,范围,是否必填等,我们通过它的子类特性Range Required 等特性

可以轻松实现对数据的验证。

   但是对于一些特殊需要的特性,系统自带的特性局限性很大,我们就可以自定义扩展需要的特性了。 

   api的开发中,存在着很多时间范围的查询,一般要求传入开始时间和结束时间 ,并且结束时间必须大于开始时间,只有这样

结束时间才有意义,那么我们就通过时间比较特性来说说如何自定义ValidationAttribute,其他情况由此发散开去。

 gogogo!

   先上核心代码 ,代码注释很全,不单独详讲

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] //指定在那些元素可以使用该特性
    public class DateTimeCompareAttribute : ValidationAttribute
    {   
        /// <summary>
        /// 开始时间(比较时间)
        /// </summary>
        public string minTime { get; set; }
        /// <summary>
        /// 特性初始化  StartTime字段为当前待比较的开始时间
        /// </summary>
        /// <param name="StartTime"></param>
        public DateTimeCompareAttribute(string StartTime)
        {
            minTime = StartTime;
        }
        /// <summary>
        /// 格式错误返回消息 非时间格式会触发 本例不需要重写
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public override string FormatErrorMessage(string name)
        {
            return base.FormatErrorMessage(name);
        }
        /// <summary>
        /// 此方法先于 IsValid(object value)调用
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var compareDate = (DateTime)value;//当前待验证的结束时间
            //validationContext.ObjectInstance 待验证对象
            //validationContext.ObjectType   待验证对象类型
            var tempData = Convert.ChangeType(validationContext.ObjectInstance, validationContext.ObjectType);//创建待验证对象
            System.Reflection.PropertyInfo propertyInfo = validationContext.ObjectType.GetProperty(minTime); //获取指定名称的属性
            if (!DateTime.TryParse(propertyInfo.GetValue(tempData, null).ToString(), out DateTime minTimeDate)) //获取属性值   
            {
                //如果开始时间也为时间格式 此代码不会进入
                return new ValidationResult($"{minTime}不是时间格式");
            }
            else
            {   //比较2个时间 如果结束时间小于等于开始时间 返回错误消息
                //可以根据业务自定义添加参数 比较是否需要等于 
                if (compareDate <= minTimeDate)
                {
                    return new ValidationResult($"{minTime}不能大于等于当前时间");
                }
            }
            return base.IsValid(value, validationContext);
        }
        /// <summary>
        /// 当前值是否有效
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool IsValid(object value)
        {
            return base.IsValid(value);
        }
    }

调用过程 实体对象部分:

        /// <summary>
        /// 起始时间
        /// </summary>
        [Required(ErrorMessage = "请输入起始时间")]
        public DateTime StartTime { get; set; }
        /// <summary>
        /// 结束时间
        /// </summary>
        [Required(ErrorMessage = "请输入结束时间")]
        [DateTimeCompare("StartTime")]
        public DateTime EndTime { get; set; }

控制器参数验证:

                if (!ModelState.IsValid)
                {
                   var errMsg= ModelState
                                     .Where(v => v.Value.Errors.Any())
                                     .Select(c => c.Value.Errors
                                     .Where(x => !string.IsNullOrWhiteSpace(x.ErrorMessage)).FirstOrDefault().ErrorMessage).FirstOrDefault();
                }

控制器中,调用对象的验证 获取验证消息 进行具体的操作处理 

后面2个代码段其实和调用系统验证是一样的,我单独提出来,让不是特别了解的同学好百度相关内容!么么哒!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章