Asp.net MVC验证那些事(4)-- 自定义验证特性
阅读目录:
一. 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标记客户端验证规则,同时客户端扩展验证方法
在实际开发中,扩展验证规则来达到数据验证的目的,能够达到代码复用的效果,同时也使得数据验证变得更加简单和方便。
推荐阅读
-
ASP.NET MVC ValidationAttribute 服务器端自定义验证
-
[Asp.Net MVC4]验证用户登录实现实例
-
Asp.net MVC验证那些事(4)-- 自定义验证特性
-
HTML5中custom data-*特性与asp.net mvc 3 表单验证
-
Asp.net MVC验证哪些事(3)-- Remote验证及其改进(附源码)
-
ASP.NET MVC自定义验证逻辑1
-
ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)
-
自定义mvc验证特性,手机号号段老增加,给自定义一个RegularExpress
-
从零开始实现asp.net MVC4框架网站的用户登录以及权限验证模块 详细教程
-
[Asp.Net MVC4]验证用户登录实现实例