当前位置: 移动技术网 > IT编程>开发语言>.net > Asp.net MVC验证那些事(4)-- 自定义验证特性

Asp.net MVC验证那些事(4)-- 自定义验证特性

2018年03月29日  | 移动技术网IT编程  | 我要评论

生物手抄报,极品笑话,173御剑江湖

在项目的实际使用中,MVC默认提供的Validation Attribute往往不够用,难以应付现实中复杂多变的验证需求。比如, 在注册用户的过程中,往往需要用户勾选”免责声明”,这个checkbox往往是必填项,但是MVC中并没有提供对于checkbox必选的验证。这篇文章通过解决checkbox必选验证的问题,看看如何在MVC中定义自己的自定义验证属性。

 

目录:

 

一. CheckBox必选验证的困局

 

二. 对于服务端ValidationAttribute的实现分析

 

三. 自定义EnforceTrueAttribute实现服务器端验证

 

四. 添加客户端验证

 

五. 总结

 

一, CheckBox必选验证的困局

 

先来引入问题,下面是我们定义的RegisterModel, 为了简化问题,只是定义了2个属性

 

复制代码

public class RegisterModel 

  { 

     [DisplayName("User Name")] 

     [Required(ErrorMessage = "User Name is required")] 

     public String UserName { get; set; }

 

     [Required] 

     public bool IsAgreeTerm { get; set; }

 

}

复制代码

我们尝试在IsAgreeTerm添加上[Required], 希望能够帮我们实现必选验证。

 

注册View页面的代码如下:

 

复制代码

@using (Html.BeginForm()) { 

    @Html.AntiForgeryToken() 

    @Html.ValidationSummary()

 

    <fieldset> 

        <legend>Registration Form</legend> 

        <ol> 

            <li> 

                @Html.LabelFor(m => m.EmployeeName) 

                @Html.EditorFor(m => m.EmployeeName) 

                <br/> 

                @Html.ValidationMessageFor(m => m.EmployeeName) 

            </li> 

             <li> 

                @Html.LabelFor(m => m.IsAgreeTerm) 

                @Html.EditorFor(m => m.IsAgreeTerm) 

                <br/> 

                @Html.ValidationMessageFor(m => m.IsAgreeTerm) 

            </li> 

      </ol> 

        <input type="submit" value="Register" /> 

    </fieldset> 

}

复制代码

接下来看看实际的运行效果:

 

验证中只是提示了User Name必填,而没有提示IsAgreeTerm。 这是因为checkbox不选的话,提交到后台的值是false, 也就是说无论如何checkbox都是有值的,[Required]验证Attribute并不能按照预想的那样为我们解决验证问题。

 

下面我们就着手实现自己的ValidationAttribute来实现该验证。

 

 

 

二, 对于服务端ValidationAttribute的实现分析

 

在实现自己的ValidationAttribute之前,我们来分析一下MVC中提供的RequiredAttribute

 

blog-requireattribute-code

 

上面能够看出, RequiredAttribute继承于ValidationAttribute抽象类, 覆盖了IsValid方法.

 

也就是说, RequiredAttribute提供了方法,用来判断添加RequiredAttribute验证规则的属性是否valid的标准。

 

实际上MVC的服务端验证流程是这样的:

 

客户端请求—>Route解析—> model绑定—> 数据验证.

 

现在思路应该比较清晰,就是同样继承ValidationAttribute, 实现我们的CheckboxRequiredAttribute.

 

三, 自定义EnforceTrueAttribute实现服务器端验证

 

这里我们定义个EnforceTrueAttribute继承ValidationAttribute

 

复制代码

public class EnforceTrueAttribute : ValidationAttribute 

   { 

       public override bool IsValid(object value) 

       { 

           if (value == null) return false; 

           if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties."); 

           return (bool)value; 

       }

 

       public override string FormatErrorMessage(string name) 

       { 

           return "The " + name + " field must be checked in order to continue."; 

       }

 

   }

复制代码

这里覆盖了父类的2个方法IsValid和FormatErrorMessage。

 

在IsValid方法中,如果提交的checkbox的值不是true, 验证就会不通过。 

FormatErrorMessage方法,是根据字段的名称显示错误信息.

 

在IsAgreeTerm上应用上EnforceTrueAttribute.

 

[DisplayName("Term")] 

[EnforceTrue] 

public bool IsAgreeTerm { get; set; }

编译运行,提交表单之后的效果是这样的:

 

blog2-cnblogs.com 

 

四, 添加客户端验证

 

我们不仅仅希望服务端验证,也同时想加上客户端验证。

 

4.1 在EnforceTrueAttribute上实现IClientValidatable

 

要实现客户端验证,首先需要在服务端的EnforceTrueAttribute上实现IClientValidatable

 

复制代码

public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable 

    public override bool IsValid(object value) 

    { 

        if (value == null) return false; 

        if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties."); 

        return (bool)value; 

    }

 

    public override string FormatErrorMessage(string name) 

    { 

        return "The " + name + " field must be checked in order to continue."; 

    }

 

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

    { 

        yield return new ModelClientValidationRule 

        { 

            ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage, 

            ValidationType = "enforcetrue" 

        }; 

    } 

}

复制代码

上面代码中,我们实现了IClientValidatable接口的方法GetClientValidationRules, 该方法返回了ModelClientValidationRule,包含了的信息ValidationType 和ErrorMessage.

 

对比一下,在EnforceTrueAttribute在实现IClientValidatable接口前后,生成前段的html差别,就能知道改方法的作用了.

 

blog-mvc-validation

 

4.2 扩展客户端验证方法

 

通过实现IClientValidatable接口,我们只是做到了给应用了该标签的input, 在生成html代码时候,添加上了额外的验证规则,但是这些规则在客户端上,还没有方法来验证。下面就是扩展客户端验证框架unobtrusive来实现完整的客户端验证流程。

 

复制代码

<script type="text/javascript"> 

      jQuery.validator.addMethod("enforcetrue", function(value, element, param) { 

          return element.checked; 

      }); 

      jQuery.validator.unobtrusive.adapters.addBool("enforcetrue"); 

  </script>

复制代码

五, 总结

 

到这里,对于完成添加一个自定义验证需要完成的流程应该是比较清楚了。

 

1. 服务端创建ValidationAttribute继承ValidationAttribute, 实现服务端的验证

2. ValidationAttribute继承IClientValidatable接口为生成的input标记客户端验证规则,同时客户端扩展验证方法

 

在实际开发中,扩展验证规则来达到数据验证的目的,能够达到代码复用的效果,同时也使得数据验证变得更加简单和方便。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网