zoukankan      html  css  js  c++  java
  • 在Asp.Net MVC中实现RequiredIf标签对Model中的属性进行验证

    在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/ 

  • 相关阅读:
    Django admin的一些有用定制
    django后台中如何在result_list内优雅的显示及使用过滤器?
    DataFrame 的函数
    pandas的替换和部分替换(replace)
    HTML5中的Web Notification桌面右下角通知功能的实现
    sqlalchemy 实现select for update
    SQLAlchemy 使用经验 (查询 事务 锁表)
    concat()
    某数据防泄漏 越权修改管理员密码
    齐治堡垒机 远程命令执行漏洞[CNVD-2019-20835]
  • 原文地址:https://www.cnblogs.com/mingmingruyuedlut/p/3520690.html
Copyright © 2011-2022 走看看