Makla
Makla

Reputation: 10459

Model validation: RequireIfNull attribute (ASP.NET Core)

I would need RequiredIfNull attribute for model validation. How can I add conditional Required attribute. Condition would depend on another property. If that property value is null, then this shouldn't be.

Something like that:

public class MyModel
{
    public int? prop1 { get; set; }

    [ConditionalRequired(prop1)]        //if prop1 == null, then prop2 is required, otherwise MyModel is invalid
    public int? prop2 { get; set; }
}

Upvotes: 0

Views: 125

Answers (1)

regnauld
regnauld

Reputation: 4336

You need a custom validation attribute. For example:

using System.ComponentModel.DataAnnotations;
using System.Reflection;

    [AttributeUsage(AttributeTargets.Property)]
    public class RequiredIfNullAttribute : ValidationAttribute
    {
        private const string DefaultErrorMessageFormat = "The {0} field is required.";

        public RequiredIfNullAttribute(string otherProperty)
        {
            if (otherProperty == null)
            {
                throw new ArgumentNullException(nameof(otherProperty));
            }

            OtherProperty = otherProperty;
            ErrorMessage = DefaultErrorMessageFormat;
        }

        public string OtherProperty { get; }

        protected override ValidationResult IsValid(object value, 
            ValidationContext validationContext)
        {
            if (value == null)
            {
                var otherProperty = validationContext.ObjectInstance.
                    GetType().GetProperty(OtherProperty);
                object otherPropertyValue = otherProperty.GetValue(
                    validationContext.ObjectInstance, null);

                if (otherPropertyValue == null)
                {
                    return new ValidationResult(
                        string.Format(ErrorMessageString, validationContext.DisplayName));
                }
            }

            return ValidationResult.Success;
        }
    }

Then in your model:

public class MyModel
{
    public int? prop1 { get; set; }

    [RequiredIfNull(nameof(prop1))]
    public int? prop2 { get; set; }
}

Things will get more complex if you also need to add client side validation.

Upvotes: 2

Related Questions