1 minute read

Introduction

When working with form submissions in C# .NET, business logic may require dependencies between form fields. For example, if a form has two fields, Type License and DEA Number, selecting the option MD - Physician should make the DEA Number field required.

screenshot1

How do we achieve this?

  • Use custom validation or ValidationAttribute
  • Create a dependent or situational validator

Create Situational Validator

public class SituationalValidator : ValidationAttribute
{
    public string DependentField { get; set; }

    // Constructor to initialize the dependent field
    public SituationalValidator(string dependentField)
    {
        DependentField = dependentField;
    }

    // Override the IsValid method to include custom validation logic
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // Get the object instance and validation context
        object instance = validationContext.ObjectInstance;
        if (validationContext != null && instance != null && !String.IsNullOrWhiteSpace(validationContext.MemberName))
        {
            Type type = instance.GetType();
            PropertyInfo dependentInfo = type.GetProperty(DependentField);
            if (dependentInfo == null)
                return new ValidationResult(String.Format("Invalid dependency: {0}", DependentField));

            // Get the value of the dependent field
            object dependentValue = dependentInfo.GetValue(validationContext.ObjectInstance, null);
            if (dependentValue == null || String.IsNullOrWhiteSpace(dependentValue.ToString()))
                return ValidationResult.Success;

            // Check if the dependent field condition is met
            bool conditionMatched = false;
            if (dependentInfo.PropertyType == typeof(bool) || dependentInfo.PropertyType == typeof(bool?))
            {
                if (!Boolean.TryParse(dependentValue.ToString(), out conditionMatched))
                    conditionMatched = false;
            }

            if (!conditionMatched)
                return ValidationResult.Success;

            // Get the value of the field being validated
            PropertyInfo propertyInfo = type.GetProperty(validationContext.MemberName);
            if (propertyInfo == null)
                return new ValidationResult(String.Format("Invalid object member: {0}", validationContext.MemberName));

            object memberValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
            if (memberValue == null || String.IsNullOrWhiteSpace(memberValue.ToString()) || memberValue.ToString() == Int16.MinValue.ToString())
                return new ValidationResult(ErrorMessage != null ? ErrorMessage : String.Format("[{0}] is required.", validationContext.MemberName));

            return ValidationResult.Success;
        }
        return new ValidationResult(String.Format("Invalid value: {0}", value));
    }
}

Next, create the dependent field IsDEARequired and use the SituationalValidator attribute on the DEA Number property.

// Declare the dependency field
[Newtonsoft.Json.JsonIgnore]
public bool IsDEARequired
{
    get
    {
        // Specify the conditions under which the DEA Number is required
        return LicenseType == "MD" || LicenseType == "NPA" || LicenseType == "PAS";
    }
}


// Apply the SituationalValidator attribute to the DEA Number property
[SituationalValidator(nameof(IsDEARequired), ErrorMessage="[DEA Number] is required.")]
public virtual string DEANumber
{
    get
    {
        // Business logic here (if any)
    }
    set
    {
        // Business logic here (if any)
    }
}

As a result, the validation will display as shown below.

screenshot2

Tags: ,

Updated: