天天看點

ASP.NETMVC Model驗證(五)

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&lt;</code><code>string</code><code>&gt; 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>///&lt;summary&gt;</code>

<code>    </code><code>/// ViewModel-使用者注冊資訊</code>

<code>    </code><code>///&lt;/summary&gt;</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,如需轉載請自行聯系原作者