在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现RequiredIf标签对Model中的属性进行验证

具体场景为:某一属性是否允许为null的验证,要根据另一个属性值是否为true来判断

代码如下所示:

1):后台代码

    public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
    {
        private RequiredAttribute innerAttribute = new RequiredAttribute();
        public string DependentProperty { get; set; }
        public object TargetValue { get; set; }

        public RequiredIfAttribute(string dependentProperty, object targetValue)
        {
            this.DependentProperty = dependentProperty;
            this.TargetValue = targetValue;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var field = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty);
            if (field != null)
            {
                var dependentValue = field.GetValue(validationContext.ObjectInstance, null);
                if (Object.Equals(dependentValue, TargetValue))
                {
                    if (!innerAttribute.IsValid(value))
                        return new ValidationResult(ErrorMessage);
                }
            }
            return ValidationResult.Success;
        }

        public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
                ValidationType = "requiredif",
            };

            string depProp = BuildDependentPropertyId(metadata, context as ViewContext);

            // find the value on the control we depend on;
            // if it's a bool, format it javascript style
            // (the default is True or False!)
            string targetValue = (TargetValue ?? "").ToString();
            if (TargetValue is bool)
                targetValue = targetValue.ToLower();

            rule.ValidationParameters.Add("dependentproperty", depProp);
            rule.ValidationParameters.Add("targetvalue", targetValue);

            yield return rule;
        }

        private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext)
        {
            // build the ID of the property
            string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty);
            // unfortunately this will have the name of the current field appended to the beginning,
            // because the TemplateInfo's context has had this fieldname appended to it. Instead, we
            // want to get the context as though it was one level higher (i.e. outside the current property,
            // which is the containing object, and hence the same level as the dependent property.
            var thisField = metadata.PropertyName + "_";
            if (depProp.StartsWith(thisField))
                // strip it off again
                depProp = depProp.Substring(thisField.Length);
            return depProp;
        }

    }

2):前台代码

$.validator.addMethod('requiredif', function (value, element, parameters) {
    var id = '#' + parameters['dependentproperty'];

    // get the target value (as a string,
    // as that's what actual value will be)
    var targetvalue = parameters['targetvalue'];
    targetvalue = (targetvalue == null ? '' : targetvalue).toString();

    // get the actual value of the target control
    // note - this probably needs to cater for more
    // control types, e.g. radios
    var control = $(id);
    if (control == null || control.length == 0) { // if control is null, the control is a checkbox or a radio
        control = $("[name='" + parameters['dependentproperty'] + "']:checked");
    }
    var controltype = control.attr('type');
    var actualvalue =
        (controltype === 'checkbox' || controltype === 'radio') ?
        control.val() != "" ? control.val() : control.prop('checked').toString() :
        control.val();

    // if the condition is true, reuse the existing
    // required field validator functionality
    if ($.trim(targetvalue) === $.trim(actualvalue) || ($.trim(targetvalue) === '*' && $.trim(actualvalue) !== ''))
        return $.validator.methods.required.call(
            this, value, element, parameters);

    return true;
});

$.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'targetvalue'], function (options) {
    options.rules['requiredif'] = {
        dependentproperty: options.params['dependentproperty'],
        targetvalue: options.params['targetvalue']
    };
    options.messages['requiredif'] = options.message;
});

将标签RequiredIf添加到对应的属性上

【注:第一个参数为相关联的属性名,第二个参数表示相关联属性值(相关联属性值=第二个参数时,再对此属性进行验证),第三个参数为错误提示信息】

        public class EricSunModel
        {
            public bool ContainsDangerousGoods { get; set; }

            [RequiredIf("ContainsDangerousGoods", true, ErrorMessage = "Please enter UN Number")]
            [Display(Name = "UN Number")]
            public string UNNumber { get; set; }
        }

更多细节请参考如下链接:

http://mvcdiary.com/2013/02/28/conditional-required-validation-or-field-mandatory-depends-on-another-field-mvc-4/

在Asp.Net MVC中实现RequiredIf标签对Model中的属性进行验证的更多相关文章

  1. 在Asp.Net MVC中实现CompareValues标签对Model中的属性进行验证

    在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现Model两个中两个属性值的比较验证 具体应用场景为:要对两个属性值的大小进行验证 代码如下所示: /// ...

  2. 在.Net MVC中自定义ValidationAttribute标签对Model中的属性做验证

    写一个继承与ValidationAttribute类的自定义的验证方法 MVC中传递数据时,大多数都会用Model承载数据,并且在传到控制器后,对Model进行一系列的验证. 我平时经常使用的判断方法 ...

  3. Asp.net mvc + .net ef database first 或 model first 时如何添加验证特性

    今天有个同事问到,在使用Entity Framework 的Database frist或model first时,怎么在model上添加验证的特性? 因为此时的Model是是VS 工具怎么生成的,直 ...

  4. CompareValues标签对Model中的属性进行验证

    在Asp.Net MVC中实现CompareValues标签对Model中的属性进行验证   在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现Model两个 ...

  5. 返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model

    原文:返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model [索引页][源码下载] 返璞归真 asp.net mvc (8) - asp.net mvc ...

  6. mvc中动态给一个Model类的属性设置验证

    原文:mvc中动态给一个Model类的属性设置验证 在mvc中有自带的验证机制,比如如果某个字段的类型是数字或者日期,那么用户在输入汉字或者英文字符时,那么编译器会自动验证并提示用户格式不正确,不过这 ...

  7. 总结ASP.NET MVC Web Application中将数据显示到View中的几种方式

    当我们用ASP.NET MVC开发Web应用程序的时候,我们都是将需要呈现的数据通过"Controllers"传输到"View"当中,怎么去实现,下面我介绍一下 ...

  8. Asp.Net MVC 从客户端&lt;a href=&quot;http://www....&quot;)中检测到有潜在危险的 Request.Form 值

    Asp.Net MVC应用程序, Framework4.0: 则需要在webconfig文件的 <system.web> 配置节中加上 <httpRuntime requestVal ...

  9. asp.net mvc 3.0 知识点整理 ----- (2).Controller中几种Action返回类型对比

    通过学习,我们可以发现,在Controller中提供了很多不同的Action返回类型.那么具体他们是有什么作用呢?它们的用法和区别是什么呢?通过资料书上的介绍和网上资料的查询,这里就来给大家列举和大致 ...

随机推荐

  1. Error : An error occurred while creating the WebJob schedule: Response status code does not indicate success: 409 (Conflict).

    How to fix the error? the answer is simple switch from Free to Standard...

  2. 解决在VS2015下用C++开发的DLL在WIN7上无法加载运行

    首先用Dependency Walker检查该DLL依赖的库,如下图所示: 依赖的动态库除了KERNEL32.DLL.USER32.DLL外,还包括了MSVCP120D.DLL以及MSVCR120D. ...

  3. js jquery中 的数据类型

    任何一门语言, buguan 是动态的, 还是像C语言的, 都有严格的 类型 "概念的", 这个是由于 编译器和解释器要求的, 需要的. 所以在是使用像 js, jquey ,ph ...

  4. SNF开发平台WinForm之十二-发送手机短信功能调用-金笛-SNF快速开发平台3.3-Spring.Net.Framework

    1.调用前组装参数 2.调用发送信息服务脚本   .调用前组装参数: BaseSendTaskEntity entity = new BaseSendTaskEntity(); entity.Mess ...

  5. @SuppressWarnings

    http://www.cnblogs.com/fsjohnhuang/p/4040785.html 一.前言 编码时我们总会发现如下变量未被使用的警告提示: 上述代码编译通过且可以运行,但每行前面的“ ...

  6. WebService学习笔记系列(一)

    webservice主要是解决两个系统或者两个应用程序之间的远程调用,它提供了一种通过web方式访问的api,调用是跨语言.跨平台的. webservice的客户端与服务端进行交互的时候使用xml来传 ...

  7. MyBatis 注解

    注解 目标 相对应的 XML 描述 @CacheNamespace 类 <cache> 为给定的命名空间 (比如类) 配置缓存. 属性:implemetation,eviction, fl ...

  8. 解决 Linux 桌面亮度调整不工作

    工作原因开始使用Ubuntu.桌面环境为GNOME,不过亮度调整和桌面环境没多大关系. 思路: 不管是GNOME还是Unity,都会尝试自己去接管亮度调整,也就是去 /sys/class/backli ...

  9. Java 中 static 和 volatile 关键字的区别?

    static指的是类的静态成员,实例间共享 volatile跟Java的内存模型有关,线程执行时会将变量从主内存加载到线程工作内存,建立一个副本,在某个时刻写回.valatile指的每次都读取主内存的 ...

  10. ThreadPoolExecutor 源码阅读

    目录 ThreadPoolExecutor 源码阅读 Executor 框架 Executor ExecutorService AbstractExecutorService 构造器 状态 Worke ...