MVC自定义验证特性

 

提到验证特性,我们不得不注意到ValidationAttribute这个类 , ValidationAttribute继承自Attribute基类,内部定义了验证机制。IsValid方法有两个虚方法:一个是返回bool值,一个是返回ValidationResult对象

public virtual bool IsValid(object value);
protected virtual ValidationResult IsValid(object value, ValidationContext validationContext);

当我们需要定义自己的验证特性时,我想继承ValidationAttribute 那是不二之选了,与通过数据标注特性定义Model元数据类似,我们可以在作为Model的数据类型及其属性上应用相应的标注特性来定义Model验证规则。根据ErrorMessage属性,来定制显示错误消息,根据自己各项所需,定制出符合自己需求的验证特性。​

IsValid方法可以根据自己的验证逻辑,对值进行验证,当值验证未能通过的时候,会显示出ErrorMessage属性的错误消息。​

1  [__DynamicallyInvokable]
2 public string ErrorMessage { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen imag   e boundaries")] get; [__DynamicallyInvokable] set; }
3  [__DynamicallyInvokable]
4  public string ErrorMessageResourceName { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method acr   oss NGen image boundaries")] get; [__DynamicallyInvokable] set; }
5  [__DynamicallyInvokable]
6  public Type ErrorMessageResourceType { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method acros   s NGen image boundaries")] get; [__DynamicallyInvokable] set; }

 

当然,我们也可以采用资源的方式来保存错误消息定制,ErrorMessageResourceName/ErrorMessageResourceType 指定了错误消息资源项对应的名称和类型,ErrorMessageResourceType是一个只读属性,用于返回最终的错误消息文本。相比ErrorMessage,更具有优先级。​

1  public override string FormatErrorMessage(string name)
2 {
3       return string.Format(CultureInfo.CurrentCulture, this.ErrorMessage, new object[] { name });
4 }

 

为了让定义的资源文本能够最大限度地被重用,我们倾向于定义一个包含占位符的文本模板,通过重写FormatErrorMessage方法,对ErrorMessage中的字符串信息进行替换。该方法name,对应的是显示名称。

1 public interface IClientValidatable
2 {
3 IEnumerable<ModelClientValidationRule>  GetClientValidationRules(ModelMetadata metadata, ControllerContext context);
4 }

 

为了减少服务器资源的消耗,我们对前端也进行验证,所以,开始要注意到IClientValidatable接口了,IClientValidatable提供了GetClientValidationRules客户端验证,通过这个方法,可以在页面上生成相关的客户端验证规则,以达到前台的验证。

1 public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)

 

GetClientValidationRules方法提供了两个参数模型元数据和控制器上下文,方法内部,可以通过metadata获得模型的一些属性值,比如显示名称。

  该方法返回的是一个实体客户端验证规则,该规则类中有三个属性:

1  public string ErrorMessage { get; set; }
2  public IDictionary<string, object> ValidationParameters { get; }
3  public string ValidationType { get; set; }

 

 ValidationType属性需设置成与客户端添加的验证方法一致,才能达到验证效果。

  接着,我们往下走..

  有时候,我们提交Html代码到服务器端的时候,会遇到“从客户端检测到有潜在危险的Request.Form 值”错误提示,这时候,我们怎么办呢?这时候可以开始动用模型元数据的RequestValidationEnabled,这个属性是设置是否启用验证值,当设置为flase的时候,可以提交html代码到后台,默认会为"<"等危险的尖角符号进行转码,我们来看看ModelMetadata这个类:

1 public virtual string Description {get;set;}   //获取或设置描述文本
2 public virtual string DisplayName {get;set;}  //当模型的名称显示时,在 UI 获取或设置该文本。
3 public virtual bool ShowForDisplay{get;set;}    //获取或设置指定的值是否在 UI 中显示模式则应将该模型 (而不只是编辑模式)。
4 public virtual bool ShowForEdit {get;set;}    //获取或设置指定的值是否应显示属性编辑模式 (与显示模式)。
5  public virtual string TemplateHint {get;set;} //获取或设置该值指示模板 (数据绑定控件) 应使用 UI 对模型。
6  public virtual string Watermark{get;set;}     //获取或设置文本框的水印文本。
7  public object Model { get; set; }             //获取或设置属性的值
8  public virtual bool RequestValidationEnabled { get;set;}  //获取或设置指定的值请求验证是否启用。
9  public virtual Dictionary<string, object> AdditionalValues{get;set;} //获取包含有关模型的其他元数据的收集。

 

 在这里,可以通过设置模型元数据的各项属性,来完成自己的需求。这只是经常用到的几个,其他我就不一一列举了。在这里,我要介绍一个方便扩展的属性:AdditionalValues,因其为字典类型,所有可以很方便的扩展其他数据属性值,比如,就拿UI的显示长度UILength为例,当然,要创建:IMetadataAware接口。

1 public interface IMetadataAware
2 {
3     // Methods
4     void OnMetadataCreated(ModelMetadata metadata);
5  }

 

实现接口:

1  public virtual void OnMetadataCreated(ModelMetadata metadata)
2 {
3              metadata.AdditionalValues.Add("UILength", 100);
4 }

 

那么,如何在前台获取设置的值呢?

1 @ViewData.ModelMetadata.AdditionalValues["UILength"]

 

除了这个属性,TemplateHint属性用起来也很灵活,指定了其属性值,可以对其指定UI显示模板。

好了,今天就写到这,感觉自己还有很多方面需要提升啊,知道的太少了。

 

 

  

posted @ 2013-01-02 11:24  虔城墨客  阅读(534)  评论(1编辑  收藏  举报