ASP.NET MVC 3 Data Annotation: Add validation dynamically

前端 未结 3 1685
北荒
北荒 2021-02-18 22:52

I\'m new with data annotation. I\'d like to know if it possible (and how) to add some validation dynamically. It is very extensive to explain why, but I\'ve a ViewModel that rec

3条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-18 23:54

    Custom Attribute:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
    public class CustomRequiredIfAttribute : CustomAttribute
    {
        private RequiredAttribute innerAttribute = new RequiredAttribute();
        public string DependentProperty { get; set; }
        public object TargetValue { get; set; }
    
        public CustomRequiredIfAttribute()
        {
        }
    
        public CustomRequiredIfAttribute(string dependentProperty, object targetValue)
            : base()
        {
            this.DependentProperty = dependentProperty;
            this.TargetValue = targetValue;
        }
    
        public override bool IsValid(object value)
        {
            return innerAttribute.IsValid(value);
        }
    }
    


    Custom RequiredIfValidator

    using System;
    using System.Collections.Generic;
    using System.Web.Mvc;
    
    namespace Custom.Web.Validation
    {
        public class RequiredIfValidator : DataAnnotationsModelValidator
        {
            public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, CustomRequiredIfAttribute attribute)
                : base(metadata, context, attribute)
            {
            }
    
            public override IEnumerable GetClientValidationRules()
            {
                return base.GetClientValidationRules();
            }
    
            public override IEnumerable Validate(object container)
            {
                // get a reference to the property this validation depends upon
                var field = Metadata.ContainerType.GetProperty(Attribute.DependentProperty);
    
                if (field != null)
                {
                    // get the value of the dependent property
                    object value = field.GetValue(container, null);
    
                    // compare the value against the target value
                    if (this.IsEqual(value) || (value == null && Attribute.TargetValue == null))
                    {
                        // match => means we should try validating this field
                        if (!Attribute.IsValid(Metadata.Model))
                        {
                            // validation failed - return an error
                            yield return new ModelValidationResult { Message = ErrorMessage };
                        }
                    }
                }
            }
    
            private bool IsEqual(object dependentPropertyValue)
            {
                bool isEqual = false;
    
                if (Attribute.TargetValue != null && Attribute.TargetValue.GetType().IsArray)
                {
                    foreach (object o in (Array)Attribute.TargetValue)
                    {
                        isEqual = o.Equals(dependentPropertyValue);
                        if (isEqual)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    isEqual = Attribute.TargetValue.Equals(dependentPropertyValue);
                }
    
                return isEqual;
            }
        }
    }
    


    Register custom DataAnnotationsModelValidatorProvider

    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomRequiredIfAttribute), typeof(RequiredIfValidator));
    


    Use this CustomRequiredIf in the ViewModel

    [CustomRequiredIf("CategoryId", 3, ErrorMessageResourceName = GlobalResourceLiterals.AccountGroup_Required)]
    public string AccountGroup { get; set; }
    

提交回复
热议问题