MVC验证03-自定义验证规则、禁止输入某些值

原文: MVC验证03-自定义验证规则、禁止输入某些值

本文继续体验自定义验证规则,需求是禁止输入某些值。本文与前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>
}

效果:

禁止输入某些值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值