Search code examples
c#asp.netasp.net-corevalidationattribute

Pass Property of Class to ValidationAttribute


I am trying to write my own ValidationAttribute for which I want to pass the value of a parameter of my class to the ValidationAttribute. Very simple, if the boolean property is true, the property with the ValidationAttribute on top should not be null or empty.

My class:

public class Test
{
    public bool Damage { get; set; }
    [CheckForNullOrEmpty(Damage)]
    public string DamageText { get; set; }
    ...
}

My Attribute:

public class CheckForNullOrEmpty: ValidationAttribute
{
    private readonly bool _damage;

    public RequiredForWanrnleuchte(bool damage)
    {
        _damage = damage;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        string damageText = validationContext.ObjectType.GetProperty(validationContext.MemberName).GetValue(validationContext.ObjectInstance).ToString();
        if (_damage == true && string.IsNullOrEmpty(damageText))
            return new ValidationResult(ErrorMessage);

        return ValidationResult.Success;
    }
}

However, I cannot simply pass the property inside the class to the ValidationAttribute like that. What would be a solution to pass the value of that property?


Solution

  • Instead of passing the bool value to the CheckForNullOrEmptyAttribute, you should pass the name of the corresponding property; within the attribute, you then can retrieve this bool value from the object instance being validated.

    The CheckForNullOrEmptyAttribute below, can be applied on your model as shown here.

    public class Test
    {
        public bool Damage { get; set; }
    
        [CheckForNullOrEmpty(nameof(Damage))] // Pass the name of the property.
        public string DamageText { get; set; }
    }
    

    public class CheckForNullOrEmptyAttribute : ValidationAttribute
    {
        public CheckForNullOrEmptyAttribute(string propertyName)
        {
            PropertyName = propertyName;
        }
    
        public string PropertyName { get; }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var hasValue = !string.IsNullOrEmpty(value as string);
            if (hasValue)
            {
                return ValidationResult.Success;
            }
    
            // Retrieve the boolean value.  
            var isRequired =
                Convert.ToBoolean(
                    validationContext.ObjectInstance
                        .GetType()
                        .GetProperty(PropertyName)
                        .GetValue(validationContext.ObjectInstance)
                    );
            if (isRequired)
            {
                return new ValidationResult(ErrorMessage);
            }
    
            return ValidationResult.Success;
        }
    }