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個代碼段其實和調用系統驗證是一樣的,我單獨提出來,讓不是特別瞭解的同學好百度相關內容!麼麼噠!

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