本文继续体验自定义验证规则,需求是禁止输入某些值。本文与前2篇相关,请参考:
MVC验证01-基础、远程验证
MVC验证02-自定义验证规则、邮件验证
自定义验证特性继承ValidationAttribute,并实现IClientValidatable接口
展开using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace MvcValidation.Extension
{
/// <summary>
/// 用来禁止属性某个值的输入
/// </summary>
public sealed class NoInputAttribute : ValidationAttribute, IClientValidatable
{
public string Input { get; set; }
public NoInputAttribute(string input)
{
this.Input = input;
}
public override bool IsValid(object value)
{
//如果没有输入值,放行
if (value == null)
{
return true;
}
if (value is string)
{
if (Input.Contains(value.ToString()))
{
return false;
}
}
return true;
}
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule
{
ValidationType = "noinput",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
};
rule.ValidationParameters["input"] = Input;
yield return rule;
}
}
}
把自定义属性打到View model的属性上
展开public class RegisterModel
{
[Required]
[StringLength(6, MinimumLength = 2)] //加
[Display(Name = "用户名")]
[NoInput("demo",ErrorMessage = "不能使用此名称")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "邮件")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "{0}栏位最少{2}个字,最多{1}个字", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "密码")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "确认密码")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
public string ConfirmPassword { get; set; }
}
[NoInput("demo",ErrorMessage = "不能使用此名称")],即当输入demo的时候就报错。
扩展jquery的验证方法jQuery.validator.noinput.js并注册
jquery的验证扩展方法的逻辑基本上与自定义特性IsValid()方法一致。
自定义特性rule.ValidationParameters["input"]的键input要传递给$.validator.unobtrusive.adapters.addSingleVal()方法。
展开//扩展的方法名与NoInputAttribute保持一致,且是小写
//value是指前端输入的值
//element是指html元素
//parm是指输入的参数,即rule.ValidationParameters["input"]键input对应的值,通过NoInputAttribute的构造函数注入的
$.validator.addMethod("noinput", function(value, element, param) {
if (value == false) { //如果value没有输入,这里就放行
return true;
}
if (value.indexOf(param) != -1) { //如果前端输入的值value包含自定义验证特性NoInputAttribute的属性Input值,就不放行
return false;
} else {
return true;
}
});
//第一个参数就是jquery验证扩展方法名
//第二个参数就是rule.ValidationParameters["input"]的键
$.validator.unobtrusive.adapters.addSingleVal("noinput", "input");
Register.cshtml视图
展开@model MvcValidation.Models.RegisterModel
@{
ViewBag.Title = "注册";
}
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>创建新帐户。</h2>
</hgroup>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<fieldset>
<legend>注册表单</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.ConfirmPassword)
@Html.PasswordFor(m => m.ConfirmPassword)
</li>
</ol>
<input type="submit" value="注册" />
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jQuery.validator.noinput.js"></script>
}
效果:
如果需要禁止多个值,需要重写自定义验证特性
这时候自定义特性的Input属性类型变成了string[],因为要判断多个值。
但前台rule.ValidationParameters["input"]存储的应该是string类型,所以保存的时候要把Input数组元素join起来。
展开using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace MvcValidation.Extension
{
/// <summary>
/// 用来禁止属性某个值的输入
/// </summary>
public sealed class NoInputAttribute : ValidationAttribute, IClientValidatable
{
public string[] Input { get; set; }
public NoInputAttribute(string input)
{
if (input.IndexOf(",") > -1)//如果输入的字符串有逗号分隔
{
//把字符串分割成数组赋值给Input
this.Input = input.Split(new char[] {‘,‘}, StringSplitOptions.RemoveEmptyEntries);
}
else
{
//没有逗号,就构建一个数组赋值给Input
this.Input = new string[]{input};
}
}
public override bool IsValid(object value)
{
//如果没有输入值,放行
if (value == null)
{
return true;
}
if (value is string)
{
if (string.Join(",", Input).Contains(value.ToString()))
{
return false;
}
}
return true;
}
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule
{
ValidationType = "noinput",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
};
rule.ValidationParameters["input"] = string.Join(",", Input);
yield return rule;
}
}
}
把自定义属性打到View model的属性上,但构造函数是用逗号分隔的字符串
展开 public class RegisterModel
{
[Required]
[StringLength(6, MinimumLength = 2)] //加
[Display(Name = "用户名")]
[NoInput("demo,jack",ErrorMessage = "不能使用此名称")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "邮件")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "{0}栏位最少{2}个字,最多{1}个字", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "密码")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "确认密码")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
public string ConfirmPassword { get; set; }
}
[NoInput("demo,jack",ErrorMessage = "不能使用此名称")],当输入demo或者jack的时候都会报错。
扩展jquery的验证方法jQuery.validator.noinput1.js并注册
需要把rule.ValidationParameters["input"]存储的值split成数组,在遍历判断。
展开//扩展的方法名与NoInputAttribute保持一致,且是小写
//value是指前端输入的值
//element是指html元素
//parm是指输入的参数,即rule.ValidationParameters["input"]键input对应的值,通过NoInputAttribute的构造函数注入的
$.validator.addMethod("noinput", function (value, element, param) {
if (value == false) { //如果value没有输入,这里就放行
return true;
}
var validateState = true;
//param就是自定义特性rule.ValidationParameters["input"]对应的值
var paramarr = param.split(‘,‘);
//第一个参数是数组元素的索引
//第二个参数是数组元素
$.each(paramarr, function(index, ele) {
if (value == ele) {
validateState = false;
return;
}
});
return validateState;
});
//第一个参数就是jquery验证扩展方法名
//第二个参数就是rule.ValidationParameters["input"]的键
$.validator.unobtrusive.adapters.addSingleVal("noinput", "input");
Register.cshmtl要引用jQuery.validator.noinput1.js
展开@model MvcValidation.Models.RegisterModel
@{
ViewBag.Title = "注册";
}
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>创建新帐户。</h2>
</hgroup>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<fieldset>
<legend>注册表单</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.PasswordFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.ConfirmPassword)
@Html.PasswordFor(m => m.ConfirmPassword)
</li>
</ol>
<input type="submit" value="注册" />
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jQuery.validator.noinput1.js"></script>
}
效果:
MVC验证03-自定义验证规则、禁止输入某些值,古老的榕树,5-wow.com