c# 數(shù)據(jù)標(biāo)注與數(shù)據(jù)校驗(yàn)
數(shù)據(jù)標(biāo)注(Data Annotation)是類或類成員添加上下文信息的一種方式,在 C# 通常用特性(Attribute)類來(lái)描述。它的用途主要可以分為下面這三類:
- 驗(yàn)證 Validation:向數(shù)據(jù)添加驗(yàn)證規(guī)則
- 顯示 Display:指定數(shù)據(jù)如何呈現(xiàn)給用戶
- 模型 Modelling:添加關(guān)于用法和與其它類的關(guān)系信息
下面是一個(gè)用來(lái)驗(yàn)證和展現(xiàn)用戶信息的一個(gè) Model:
class Kid { [Range(0, 18)] // 年齡不能超過(guò)18歲,不能為負(fù)數(shù) public int Age { get; set; } [StringLength(MaximumLength = 50, MinimumLength = 3)] // 名稱的長(zhǎng)度不能超過(guò) 50,不能小于 3 public string Name { get; set; } [DataType(DataType.Date)] // 生日將作為日期展示 (不帶時(shí)間) public DateTime Birthday { get; set; } }
數(shù)據(jù)標(biāo)注的顯示用途主要在早期的 ASP.NET 和 ASP.NET MVC 等框架中使用。例如,在 ASP.NET MVC 中,Razor 引擎會(huì)根據(jù) Model 屬性的 DataType 特性動(dòng)態(tài)生成不同類型的表單元素。不過(guò),現(xiàn)在這類用途除了 WPF(比如 EditableAttribute
)已經(jīng)過(guò)時(shí)很少用了。
數(shù)據(jù)標(biāo)注用來(lái)驗(yàn)證數(shù)據(jù)的合法性是最常見(jiàn)的用法,在 ASP.NET Core/Mvc 中,數(shù)據(jù)作為表單 Model 提交時(shí),框架會(huì)對(duì) Model 數(shù)據(jù)自動(dòng)進(jìn)行校驗(yàn),也可以手動(dòng)調(diào)用 ModelState.IsValid()
來(lái)判斷數(shù)據(jù)是否合法。
自定義校驗(yàn)特性
自定義一個(gè)校驗(yàn)特性很簡(jiǎn)單,創(chuàng)建一個(gè)繼承 ValidationAttribute
的類,然后重寫它的 IsValid
方法。示例:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public class EvenNumberAttribute : ValidationAttribute { public override bool IsValid(object input) { if (input == null) return false; if (!int.TryParse(input.ToString(), out int val)) return false; return val % 2 == 0; } }
然后這個(gè)特性可以這么用:
public class Model { [EvenNumberAttribute(ErrorMessage = "數(shù)字必須是偶數(shù)")] public int MyNumber { get; set; } }
除了這自定義校驗(yàn)的方式,C# 還提供了一個(gè) CustomValidation
特性,也是用來(lái)自定義數(shù)據(jù)校驗(yàn)的,它是通過(guò)反射的方式來(lái)實(shí)現(xiàn)的。示例:
public class Model { [CustomValidation(typeof(MyCustomValidation), "IsNotEvenNumber")] public int MyNumber { get; set; } } public static class MyCustomValidation { public static ValidationResult IsNotEvenNumber(object input) { var result = new ValidationResult("數(shù)字必須是偶數(shù)"); if (input == null || !int.TryParse(input.ToString(), out int val)) return result; return val % 2 == 0 ? ValidationResult.Success : result; } }
C# 內(nèi)置了很多常用數(shù)據(jù)校驗(yàn)特性類,比如最常用的 RequiredAttribute
、StringLengthAttribute
、RangeAttribute
等。
手動(dòng)執(zhí)行數(shù)據(jù)校驗(yàn)
大多數(shù)時(shí)候,數(shù)據(jù)校驗(yàn)都是由框架(如 ASP.NET Core)幫我們做了,但有時(shí)候我們想手動(dòng)執(zhí)行校驗(yàn)數(shù)據(jù)怎么做呢?簡(jiǎn)單說(shuō),使用 Validator
類即可,但也不是想像的那么直接。數(shù)據(jù)校驗(yàn)需要提供檢驗(yàn)的信息,比如校驗(yàn)規(guī)則、需要校驗(yàn)的屬性及未通過(guò)顯示的錯(cuò)誤信息等,而這些需要由另一個(gè)類來(lái)從待校驗(yàn)的實(shí)例中提取作為上下文,它是 ValidationContext
,所以需要先創(chuàng)建 ValidationContext
對(duì)象:
ValidationContext vc = new ValidationContext(objectToValidate);
創(chuàng)建好這個(gè)上下文對(duì)象就可以對(duì)數(shù)據(jù)進(jìn)行多種方式的校驗(yàn)了,比如校驗(yàn)對(duì)象的所有屬性:
ValidationContext vc = new ValidationContext(objectToValidate); ICollection<ValidationResult> results = new List<ValidationResult>(); bool isValid = Validator.TryValidateObject(objectToValidate, vc, results, true);
也可以只校驗(yàn)對(duì)象的指定屬性:
ValidationContext vc = new ValidationContext(objectToValidate); ICollection<ValidationResult> results = new List<ValidationResult>(); bool isValid = Validator.TryValidatePropery(objectToValidate.PropertyToValidate, vc, results, true);
返回值 isValid 表示是否所有數(shù)據(jù)都驗(yàn)證通過(guò),驗(yàn)證失敗的信息會(huì)放到 results 結(jié)果集。
看到這,我覺(jué)得手動(dòng)執(zhí)行校驗(yàn)還是有點(diǎn)麻煩,創(chuàng)建 ValidationContext
對(duì)象這一步如果也封裝在 Validator
類的方法內(nèi),豈不是簡(jiǎn)潔一些?
作者:精致碼農(nóng)
出處:http://cnblogs.com/willick
聯(lián)系:liam.wang@live.com
以上就是c# 數(shù)據(jù)標(biāo)注與數(shù)據(jù)校驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于c# 數(shù)據(jù)標(biāo)注與數(shù)據(jù)校驗(yàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#日期格式字符串的相互轉(zhuǎn)換操作實(shí)例分析
這篇文章主要介紹了C#日期格式字符串的相互轉(zhuǎn)換操作,結(jié)合實(shí)例形式分析了C#日期格式字符串的相互轉(zhuǎn)換操作函數(shù)與相關(guān)使用技巧,需要的朋友可以參考下2019-08-08淺析C#中數(shù)組,ArrayList與List對(duì)象的區(qū)別
在C#中,當(dāng)我們想要存儲(chǔ)一組對(duì)象的時(shí)候,就會(huì)想到用數(shù)組,ArrayList,List這三個(gè)對(duì)象了。那么這三者到底有什么樣的區(qū)別呢2013-07-07Unity?UGUI的RawImage原始圖片組件使用示例詳解
這篇文章主要為大家介紹了Unity?UGUI的RawImage原始圖片組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07C#實(shí)現(xiàn)漢字轉(zhuǎn)漢語(yǔ)拼音的示例代碼
這篇文章主要介紹了如何利用C#實(shí)現(xiàn)漢字轉(zhuǎn)漢語(yǔ)拼音,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定幫助,感興趣的小伙伴可以跟隨小編一起動(dòng)手試一試2022-03-03關(guān)于c#二叉樹(shù)的實(shí)現(xiàn)
本篇文章小編為大家介紹,關(guān)于c#二叉樹(shù)的實(shí)現(xiàn)。需要的朋友參考下2013-04-04C#實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音功能
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03wpf將表中數(shù)據(jù)顯示到datagrid示例
這篇文章主要介紹了wpf將表中數(shù)據(jù)顯示到datagrid示例,需要的朋友可以參考下2014-02-02C#中讓控件全屏顯示的實(shí)現(xiàn)代碼(WinForm)
有時(shí)候需要讓窗口中某一塊的內(nèi)容全屏顯示,比如視頻播放、地圖等等。經(jīng)過(guò)摸索,暫時(shí)發(fā)現(xiàn)兩種可行方法,如果有誰(shuí)知道其他方法,敬請(qǐng)告知2012-04-04