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