ASP.NETMVC Model驗證(五)
前言
上篇主要講解ModelValidatorProvider和ModelValidator兩種類型的自定義實作,然而在MVC架構中還給我們提供了其它方式來進行Model驗證,也就是本篇的主題,使用架構提供給我們的一系列的特性類型來進行Model驗證,當然也是可以自定義的,在下面的示範示例中,我會使用我們自己自定義的特性類型(繼承自ValidationAttribute類型)到自定義Model綁定器中來模拟一下實作。
Model驗證
Model驗證簡單運用示例
ModelValidator使用生成過程
自定義實作DefaultModelBinder進行驗證
自定義ModelValidatorProvider 和ModelValidator
ValidationAttribute特性類使用
自定義ValidationAttribute特性類的示例實作
我們首先看一下ValidationAttribute類型的定義,示例代碼1-1。
代碼1-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<code>public</code> <code>abstract</code> <code>class</code> <code>ValidationAttribute: Attribute</code>
<code> </code><code>{</code>
<code> </code><code>protectedValidationAttribute();</code>
<code> </code><code>protectedValidationAttribute(Func<</code><code>string</code><code>> errorMessageAccessor);</code>
<code> </code><code>protectedValidationAttribute(</code><code>string</code> <code>errorMessage);</code>
<code> </code>
<code> </code><code>// 摘要:</code>
<code> </code><code>// 擷取或設定一條在驗證失敗的情況下與驗證控件關聯的錯誤消息。</code>
<code> </code><code>//</code>
<code> </code><code>// 傳回結果:</code>
<code> </code><code>// 與驗證控件關聯的錯誤消息。</code>
<code> </code><code>public</code> <code>string</code> <code>ErrorMessage { </code><code>get</code><code>;</code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>ErrorMessageResourceName { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>Type ErrorMessageResourceType { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>protectedstring ErrorMessageString { </code><code>get</code><code>; }</code>
<code> </code><code>public</code> <code>virtual</code> <code>stringFormatErrorMessage(</code><code>string</code> <code>name);</code>
<code> </code><code>public</code> <code>ValidationResult GetValidationResult(</code><code>object</code> <code>value, ValidationContextvalidationContext);</code>
<code> </code><code>// 确定對象的指定值是否有效。</code>
<code> </code><code>// 參數:</code>
<code> </code><code>// value:</code>
<code> </code><code>// 要驗證的對象的值。</code>
<code> </code><code>// 如果指定的值有效,則為 true;否則,為 false。</code>
<code> </code><code>public</code> <code>virtual</code> <code>bool</code> <code>IsValid(</code><code>object</code> <code>value);</code>
<code> </code><code>protectedvirtual ValidationResultIsValid(</code><code>object</code> <code>value, ValidationContextvalidationContext);</code>
<code> </code><code>public</code> <code>void</code> <code>Validate(objectvalue, </code><code>string</code> <code>name);</code>
<code> </code><code>public</code> <code>void</code> <code>Validate(objectvalue, ValidationContext validationContext);</code>
<code>}</code>
ValidationAttribute類型就是下面示例中所有應用在Model屬性上特性類型的基類,在上面的ValidationAttribute類型中ErrorMessage屬性表示驗證錯誤所顯示資訊,IsValid()方法則是表示驗證的值是否通過,下面我們看一下架構給我們提供的Model驗證特性類的簡單示例。
首先我們還是使用ASP.NETMVC Model驗證(一)中的示例代碼,看一下ViewModel使用了驗證特性類後的定義,示例代碼1-2.
代碼1-2
<code>namespace</code> <code>MvcApplication.Models</code>
<code>{</code>
<code> </code><code>///<summary></code>
<code> </code><code>/// ViewModel-使用者注冊資訊</code>
<code> </code><code>///</summary></code>
<code> </code><code>public</code> <code>class</code> <code>RegistrationInformation</code>
<code> </code><code>[Required]</code>
<code> </code><code>public</code> <code>string</code> <code>ID { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>public</code> <code>string</code> <code>UserID { </code><code>get</code><code>; </code><code>set</code><code>; }</code>
<code> </code><code>[StringLength(10)]</code>
<code> </code><code>public</code> <code>string</code> <code>Password1 { </code><code>get</code><code>;</code><code>set</code><code>; }</code>
<code> </code><code>[Compare(</code><code>"Password1"</code><code>)]</code>
<code> </code><code>public</code> <code>string</code> <code>Password2 { </code><code>get</code><code>;</code><code>set</code><code>; }</code>
<code> </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>}</code>
在代碼1-2中,我們看到了一些應用于Model屬性上的特性類,下面簡單的說一下這幾種類型的含義。
Required:[Required],表示此屬性不得為空(包括空字元串),當然了也可以通過設定内部的AllowEmptyStrings屬性為true後,則視為可以為空。
StringLength:[StringLength(10)],表示此屬性值的字元串最大長度不能超過10。
Compare:[Compare(“Password1”)],表示此屬性的值必須和指定屬性的值相同,示例中就是Password2的值必須和Password1屬性的值相同,不然就會提示驗證的錯誤資訊
下面來一下項目運作後的結果圖,
圖1
<a href="http://s3.51cto.com/wyfs02/M00/3D/BA/wKiom1PFI12Dr2s7AAEacGWHlNQ222.jpg" target="_blank"></a>
圖1中故意輸入的這些數值,看下圖2是驗證後的結果
圖2
<a href="http://s3.51cto.com/wyfs02/M01/3D/BA/wKiom1PFI2_S43u3AAGvskUfCH4947.jpg" target="_blank"></a>
這一小節我們直接來看自定義Model驗證特性類型,直接來看定義的示例代碼1-3.
代碼1-3
<code>namespace</code> <code>MvcApplication.ModelValidators</code>
<code> </code><code>[AttributeUsage(AttributeTargets.Property,AllowMultiple=</code><code>true</code><code>,Inherited=</code><code>false</code><code>)]</code>
<code> </code><code>public</code> <code>class</code> <code>CustomModelValidatorAttribute:ValidationAttribute</code>
<code> </code><code>public</code> <code>override</code> <code>boolIsValid(</code><code>object</code> <code>value)</code>
<code> </code><code>{</code>
<code> </code><code>if</code><code>(</code><code>string</code><code>.IsNullOrEmpty((</code><code>string</code><code>)value)|| </code><code>string</code><code>.Compare((</code><code>string</code><code>)value,</code><code>"jinyuan"</code><code>, </code><code>true</code><code>) == 0)</code>
<code> </code><code>{</code>
<code> </code><code>ErrorMessage = </code><code>"不能為空,或名稱不合法!"</code><code>;</code>
<code> </code><code>returnfalse;</code>
<code> </code><code>}</code>
<code> </code><code>else</code>
<code> </code><code>returntrue;</code>
<code> </code><code>}</code>
這裡為什麼要重寫基類的IsValid()方法,可能MVC架構會調用這個方法來判斷目前值是否通過驗證,這裡說一句題外話,在MVC架構中我翻看過預設綁定器類型的實作代碼,并沒有找到對Model驗證特性類的調用,哪位大神知道的話告知一下小弟感激不盡。
現在我們再修改一下代碼1-2中的定義,示例代碼1-4.
代碼1-4
<code> </code><code>[CustomModelValidator]</code>
修改過後我們看一下結果圖3和圖4.
圖3
<a href="http://s3.51cto.com/wyfs02/M01/3D/BA/wKioL1PFI5HjrxZsAAEfNAVuxvU698.jpg" target="_blank"></a>
圖4
<a href="http://s3.51cto.com/wyfs02/M01/3D/BB/wKiom1PFI9PzsuJsAAHLo-yrRZ0597.jpg" target="_blank"></a>
看到這裡,有點不死心,想模拟實作一下預設綁定器的内部實作,這部分内容僅供參考,示例代碼1-5.
代碼1-5
<code> </code><code>public</code> <code>class</code> <code>CustomModelValidatorAttributeModelBinder: DefaultModelBinder</code>
<code> </code><code>protectedoverride voidSetProperty(ControllerContextcontrollerContext, ModelBindingContextbindingContext, PropertyDescriptorpropertyDescriptor, </code><code>object</code> <code>value)</code>
<code> </code><code>base</code><code>.SetProperty(controllerContext,bindingContext, propertyDescriptor, value);</code>
<code> </code><code>foreach</code><code>(Attribute att inpropertyDescriptor.Attributes)</code>
<code> </code><code>if</code><code>(att </code><code>is</code> <code>ModelValidators.CustomModelValidatorAttribute)</code>
<code> </code><code>{</code>
<code> </code><code>ModelValidators.CustomModelValidatorAttribute mva = att </code><code>as</code> <code>ModelValidators.CustomModelValidatorAttribute;</code>
<code> </code><code>if</code><code>(!mva.IsValid(value))</code>
<code> </code><code>{</code>
<code> </code><code>bindingContext.ModelState.AddModelError(propertyDescriptor.Name,mva.ErrorMessage);</code>
<code> </code><code>}</code>
<code> </code><code>}</code>
在代碼1-5中我們根據PropertyDescriptor類型的參數擷取到應用在Model屬性上的所有特性類,然後篩選到我們自定義的類型,進行一個驗證判斷然後将其錯誤資訊添加到ModelState中,需要把我們自定義的這個Model綁定器注冊到系統中,運作的時候按照圖3的輸入,結果就跟圖4一樣。同樣的都能實作功能,這裡隻是讓大家對預設的綁定器營造個遐想的空間。
本文轉自jinyuan0829 51CTO部落格,原文連結:http://blog.51cto.com/jinyuan/1438617,如需轉載請自行聯系原作者