<b>閱讀目錄</b>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html#_label0">1.基本介紹</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html#_label1">2.建立驗證器</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html#_label2">3.針對相同屬性的鍊式程式設計驗證</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html#_label3">4.驗證結果</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html#_label4">5.異常與複雜驗證</a>
<a href="http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html#_label5">6.靈活的驗證規則組設定</a>
為了保持内容的完整性,大部分内容我都是參考FluentValidation提供的幫助文檔,自己經過翻譯和了解加工。更好的呈現給大家。
NuGet Packages:Install-Package FluentValidation
ASP.NET MVC內建包:Install-Package FluentValidation.MVC5
下面我們将從一個簡單的驗證器的建立以及使用來介紹它的基本功能。
使用之前,要引用FluentValidation.dll,太簡單,就省略了吧。為了給特定的對象定義一組驗證規則,必須建立一個繼承AbstractValidator<T>的類,T是需要驗證的類型。例如,假設我們有一個Customer類,如下所示:
1
2
3
4
5
6
7
<code>public</code> <code>class</code> <code>Customer {</code>
<code> </code><code>public</code> <code>int</code> <code>Id { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>Surname { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>Forename { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>decimal</code> <code>Discount { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>Address { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code>}</code>
是以按照上面要求,我們要給Customer定義一組驗證規則,就要繼承AbstractValidator<Customer>,如下面代碼:
<code>using</code> <code>FluentValidation;</code>
<code>public</code> <code>class</code> <code>CustomerValidator : AbstractValidator<Customer> </code>
<code>{</code>
驗證規則本身在驗證器的構造函數中定義。為了給特定屬性指定一個驗證規則,需要調用RuleFor方法,通過屬性的lambda表達式來進行你想要的驗證。例如,確定Surname屬性不是null,驗證器應該這樣寫:
8
9
<code>//Customer驗證器</code>
<code>public</code> <code>class</code> <code>CustomerValidator : AbstractValidator<Customer></code>
<code> </code><code>public</code> <code>CustomerValidator() </code>
<code> </code><code>{</code>
<code> </code><code>RuleFor(customer => customer.Surname).NotNull();</code>
<code> </code><code>}</code>
針對同一個屬性編寫驗證代碼時,我們可以使用鍊式的方式進行,非常友善,也容易了解。如下面的代碼:
<code> </code><code>{ </code><code>//Surname不為空,且不等于foo</code>
<code> </code><code>RuleFor(customer => customer.Surname).NotNull().NotEqual(</code><code>"foo"</code><code>);</code>
上面的注釋已經很明顯了,針對Surname屬性,直接進行判斷和編寫代碼,同樣可以寫其他的,一直寫下去。。。為了執行驗證器,我們首先要建立一個驗證器的執行個體對象,然後将要驗證的對象傳遞給Validate方法,即可進行驗證。如下面代碼:
<code>//要驗證的對象執行個體</code>
<code>Customer customer = </code><code>new</code> <code>Customer();</code>
<code>//驗證器執行個體</code>
<code>CustomerValidator validator = </code><code>new</code> <code>CustomerValidator();</code>
<code>//進行驗證操作,擷取驗證結果</code>
<code>ValidationResult results = validator.Validate(customer);</code>
至于結果的内容,請接着往下看。
在使用驗證器的Validate進行驗證後,擷取的ValidationResult對象裡面提供了2個主要資訊:
1.IsValid: 标記是否驗證成功
2.Errors :錯誤情況,驗證失敗的對象集合,包括所有驗證失敗對象的細節。
例如下面的代碼将驗證失敗的資訊列印出來:
10
11
<code>//如果驗證失敗</code>
<code>if</code><code>(! results.IsValid) {</code>
<code> </code><code>//周遊所有的失敗對象</code>
<code> </code><code>foreach</code><code>(</code><code>var</code> <code>failure </code><code>in</code> <code>results.Errors) {</code>
<code> </code><code>//失敗的屬性名稱,如錯誤資訊</code>
<code> </code><code>Console.WriteLine(</code><code>"Property "</code> <code>+ failure.PropertyName + </code><code>" failed validation. Error was: "</code> <code>+ failure.ErrorMessage);</code>
上一節中,我們看到了驗證結果的處理情況,但是在很多情況下,如果驗證失敗的情況下,要及時抛出異常給使用者,是以在驗證的時候就要注意抛出異常,FluentValidation也提供了這樣的機制,它為驗證器提供了一個ValidateAndThrow 的擴充方法。使用這個方法後,如果碰到失敗的情況,會及時抛出一個ValidationException 異常,讓業務驗證過程使用。主要代碼如下:
<code>validator.ValidateAndThrow(customer);</code>
我們前面處理的都是單個驗證器的使用,構成也基本清楚了,但如果在目前驗證的實體類中還有其他對象,也需要對這個對象進行各種屬性驗證,該怎麼辦。舉個例子,假設我們有一個 客戶類 Customer 以及位址類Address,在Customer 中包括了一個Address類型的屬性,用來存儲目前客戶的位址資訊,如下面所示代碼:
12
13
14
15
<code>//客戶類</code>
<code>public</code> <code>class</code> <code>Customer </code>
<code> </code><code>public</code> <code>string</code> <code>Name { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>Address Address { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code>//位址類</code>
<code>public</code> <code>class</code> <code>Address</code>
<code> </code><code>public</code> <code>string</code> <code>Line1 { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>Line2 { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>Town { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>County { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>Postcode { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
由于我們也需要對Address類進行,驗證,是以先類似的構造一個Address驗證器:
<code>public</code> <code>class</code> <code>AddressValidator : AbstractValidator<Address> </code>
<code> </code><code>public</code> <code>AddressValidator() </code>
<code> </code><code>{</code>
<code> </code><code>RuleFor(address => address.Postcode).NotNull(); </code>
<code> </code><code>}</code>
然後我們同理要構造CustomerValidator驗證器,在驗證Address的時候,及可以複用上面的AddressValidator,如下面代碼:
<code> </code><code>public</code> <code>CustomerValidator() </code>
<code> </code><code>RuleFor(customer => customer.Name).NotNull();</code>
<code> </code><code>//對Address使用驗證器直接進行驗證,可以重複使用代碼</code>
<code> </code><code>RuleFor(customer => customer.Address).SetValidator(</code><code>new</code> <code>AddressValidator())</code>
過程比較簡單,更加複雜的處理也類似,應該沒啥問題了。值得注意的是,如果Address 是集合類型,如List<Address> ,則要使用SetCollectionValidator來進行驗證,和SetValidator的使用類似。
假設一個Person類有3個屬性(Id,Surname,Forename),我們寫一個驗證器分别對幾個屬性進行驗證,并将其中2個的驗證規則放在一個規則集合裡面RuleSet,名稱為:Names,如下面代碼:
<code>public</code> <code>class</code> <code>PersonValidator : AbstractValidator<Person> </code>
<code> </code><code>public</code> <code>PersonValidator()</code>
<code> </code><code>{ </code><code>//名稱為 Names 的規則組</code>
<code> </code><code>RuleSet(</code><code>"Names"</code><code>, () => </code>
<code> </code><code>{</code>
<code> </code><code>RuleFor(x => x.Surname).NotNull();</code>
<code> </code><code>RuleFor(x => x.Forename).NotNull();</code>
<code> </code><code>});</code>
<code> </code><code>//其他沒有集合的組名稱,預設為:default</code>
<code> </code><code>RuleFor(x => x.Id).NotEqual(0);</code>
然後我們在驗證的時候,就可以靈活指定規則集的名稱了,一次可以指定單個或者多個,值得注意的是,沒有放在集合中的規則,預設在 default 組中。如下面的代碼:
<code>var</code> <code>validator = </code><code>new</code> <code>PersonValidator();</code>
<code>var</code> <code>person = </code><code>new</code> <code>Person();</code>
<code>//隻執行 Names 規則集</code>
<code>var</code> <code>result = validator.Validate(person, ruleSet: </code><code>"Names"</code><code>);</code>
<code>//執行 Names,MyRuleSet,SomeOtherRuleSet 規則集</code>
<code>validator.Validate(person, ruleSet: </code><code>"Names,MyRuleSet,SomeOtherRuleSet"</code><code>)</code>
<code>//執行預設的規則(不在集合中的) 和 MyRuleSet</code>
<code>validator.Validate(person, ruleSet: </code><code>"default,MyRuleSet"</code><code>)</code>
本文轉自葉小钗 h資料之巅部落格園部落格,原文連結:http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html,如需轉載請自行聯系原作者