0

I've got a website where people can apply for services. They select a product and options they'd like, along with information about themselves.

The model is divided into parts:

public class ApplicationInformationModel
{
    public int ProductType { get; set; }
    public ClientModel Client { get; set; }
    ...
}

public class ClientModel {
    public string Name { get; set; }
    [AgeValidation]
    public DateTime DateOfBirth { get; set; }
    ...
}

The age is dependent on the type of the product, but I don't have access to the ProductType variable from the ClientModel.

    public class AgeValidationAttribute : ValidationAttribute
    {
        public string GetErrorMessage() => $"The age does not fall within the acceptable range.";

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            int productType = // How do I get the productType?
            var dob = (DateTime)value;
            int age = DateTime.Now.Year - dob.Year;
            if (DateTime.Now.DayOfYear < dob.DayOfYear) age--;

            if (productType == 0 && age < 18)
            {
                return new ValidationResult(GetErrorMessage(validationContext.DisplayName));
            }
            else if (productType == 1 && age < 21)
            {
                return new ValidationResult(GetErrorMessage(validationContext.DisplayName));
            }

            return ValidationResult.Success;
        }
    }

How do I get access to the ProductType?

  • Check if this could help you https://stackoverflow.com/questions/3720823/how-do-i-access-other-attribute-values-from-inside-a-custom-validationattribute#answer-3721211 – Sowmyadhar Gourishetty Aug 10 '20 at 13:42

1 Answers1

0

implement IValidatableObject in ApplicationInformationModel

public class ApplicationInformationModel : IValidatableObject
{
    public int ProductType { get; set; }
    public ClientModel Client { get; set; }
    ...

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        //int productType = productType;

        DateTime dob = Client.DateOfBirth;
        int age = DateTime.Now.Year - dob.Year;
        if (DateTime.Now.DayOfYear < dob.DayOfYear) age--;

        if (productType == 0 && age < 18)
        {
            return new ValidationResult(GetErrorMessage(validationContext.DisplayName));
        }
        else if (productType == 1 && age < 21)
        {
            return new ValidationResult(GetErrorMessage(validationContext.DisplayName));
        }

        return ValidationResult.Success;
    }
}

Change to ClientModel has a ApplicationInformationModel.

public class ApplicationInformationModel
{
    public int ProductType { get; set; }
    ...
}

public class ClientModel {
    public string Name { get; set; }

    [AgeValidation]
    public DateTime DateOfBirth { get; set; }

    public ApplicationInformationModel applicationInformationModel { get; set; }
    ...
}

Then create a class that inherits from ValidationAttribute, and override the IsValid method.

public class AgeValidationAttribute : ValidationAttribute
{
    public string GetErrorMessage() => $"The age does not fall within the acceptable range.";

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {

        ClientModel client = (ClientModel)validationContext.ObjectInstance;

        int productType = client.applicationInformationModel.productType;

        DateTime dob = client.DateOfBirth;
        int age = DateTime.Now.Year - dob.Year;
        if (DateTime.Now.DayOfYear < dob.DayOfYear) age--;

        if (productType == 0 && age < 18)
        {
            return new ValidationResult(GetErrorMessage(validationContext.DisplayName));
        }
        else if (productType == 1 && age < 21)
        {
            return new ValidationResult(GetErrorMessage(validationContext.DisplayName));
        }

        return ValidationResult.Success;
    }
}

Links : To apply a custom validation attribute to a data field

Michael Wang
  • 3,782
  • 1
  • 5
  • 15
  • But I need the validation message to be displayed near the Date of Birth field. I realize now that may sound a little strange in this simple example I created to try and simplify my question. The product will actually be selected on a previous page and can no longer be edited when the Date of Birth is entered. – Joel MacKenzie Aug 10 '20 at 19:10
  • I don't think this will work anyway as you wouldn't be able to cast `value` to an `int` and a `DateTime`. – Joel MacKenzie Aug 10 '20 at 19:16
  • I'm sorry I didn't notice the `var dob = (DateTime)value; ` before. Already update the answer for u. – Michael Wang Aug 11 '20 at 07:43
  • Hi, @Joel MacKenzie, please let us know if you have updated information on this issue. – Michael Wang Aug 20 '20 at 08:07