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>
}

效果:

MVC验证03-自定义验证规则、禁止输入某些值,布布扣,bubuko.com

时间: 2024-10-08 19:01:32

MVC验证03-自定义验证规则、禁止输入某些值的相关文章

ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttribute应用到Model的类型或者属性上即可.对于自定义验证,我们也只需要定义相应的Validation 就可以了,不过服务端验证比较简单,而客户端验证就要稍微复杂一些,本文提供一个简单的实例说明在ASP.NET MVC中实现自定义验证的基本步骤.[源代码从这里下载] 一.AgeRangeAttr

ASP.NET MVC ValidationAttribute 服务器端自定义验证

自定义服务端验证要继承自ValidationAttribute,并重写IsValid虚方法来自定义自己的验证规则,ValidationAttribute源码如下: 1 public abstract class ValidationAttribute : Attribute 2 { 3 //验证失败提示消息 4 public virtual string FormatErrorMessage(string name); 5 6 //自定义验证一 7 protected virtual Valid

mvc 实体类 自定义验证特性

mvc 实体类验证的时候 如果有多个验证特性需要在属性上层叠很多个验证特性,显得属性特别臃肿并且也不够直观,极大地影响我使用它的兴趣,所以我想自定义一个验证特性,然后将所有需要验证的情形全部放在一个特性里,看上去更直观一点. [DataContract] public partial class Sys_Menu : BaseModel { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [DataMember] publi

angularJS添加form验证:自定义验证

刚学习form验证.不得不说form验证是比较丰富的.下面来个小例子.1.情景:看电影选座位!2.具体要求:当输入座位号时,进行校验.其中1已经被选.如果输入为1,则提交按钮置为无效,并且给出提示,如果输入为2,则不给出提示,允许提交3.实际效果: 4.代码示例: 1 <!DOCTYPE HTML> 2 <html ng-app="app"> 3 <head> 4 <meta charset="utf-8"/> 5 &

在ASP.NET MVC中使用Knockout实践06,自定义验证、异步验证

在上一篇中体验了Knockout.Validation的基本验证,本篇体验自定义验证和异步验证. 自定义验证规则 ko.validation有一个rules属性,专门用来存放验证规则,它是一个键值对集合类型,key就是自定义验证规则的名称,value是一个json对象. @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <style type="text/c

在ASP.NET MVC中使用Knockout实践07,自定义验证信息的位置与内容

在前两篇中,体验了Knockout的基本验证和自定义验证.本篇自定义验证信息的显示位置与内容. 自定义验证信息的显示位置 通常,Knockout的验证信息紧跟在input后面,通过validationMessage属性可以自定义验证信息的显示位置. @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <style type="text/css">

ASP.NET MVC的客户端验证:jQuery验证在Model验证中的实现

原文:ASP.NET MVC的客户端验证:jQuery验证在Model验证中的实现 在简单了解了Unobtrusive JavaScript形式的验证在jQuery中的编程方式之后,我们来介绍ASP.NET MVC是如何利用它实现客户端验证的.服务端验证最终实现在相应的ModelValidator中,而最终的验证规则定义在相应的ValidationAttribute中:而客户端验证规则通过HtmlHelper<TModel>相应的扩展方法(比如TextBoxFor.EditorFor和Edid

自定义验证逻辑

Asp.net MVC框架的扩展性意味着实现自定义验证逻辑有着很大的可行性.主要有两个核心方法: 1.将验证逻辑封装在自定义的数据注解中. 2.将验证逻辑封装在模型对象中. 把验证逻辑封装在自定义数据注解中可以轻松地实现在多个模型中重用逻辑,这需要在特性内部编写代码以对应不同类型的模型,一旦实现了,新的注解就可以在多处重用. 如果把验证逻辑放入模型对象中,就意味着验证逻辑可以很容易的编码实现,但不利于实现逻辑的重用. 一.自定义注解 所有的验证注解特性最终都派生自基类:ValidationAtt

angularJS中自定义验证指令中的$parsers and $formatters

本文翻译自:$parsers and $formatters in Custom Validation Directives in Angular JS 在使用angularJS的应用中,有时候我们需要定义自己的表单验证.自定义验证在angularJS中是通过创建指令来实现的,该指令依赖于ng-model指令,主要是依赖于它的controller. ng-model指令提供2个由函数组成的数组: $parsers 和 $formatters,这些函数用于实现自定义验证逻辑时调用.这两个数组的用途

自定义验证器

自定义验证器必须实现 Validator 接口. ValidatorSupport 和 FieldValidatorSupport 实现了 Validator 接口 --若需要普通的验证程序, 可以继承 ValidatorSupport 类 --若需要字段验证程序, 可以继承 FieldValidatorSupport 类 --若验证程序需要接受一个输入参数, 需要为这个参数增加一个相应的属性 注册验证程序: 自定义验证器需要在类路径里的某个 validators.xml 文件里注册:  验证框