天天看点

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,如需转载请自行联系原作者