0

I am using asp.net core 2.0 and I have a custom validation attribute for validating age.

public class ValidAgeAttribute : ValidationAttribute 
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {          
        var model = validationContext.ObjectInstance as FormModel;

        var db =  model.DOB.AddYears(100);

        if (model == null)
            throw new ArgumentException("Attribute not applied on Model");

        if (model.DOB > DateTime.Now.Date)
            return new ValidationResult($"{validationContext.DisplayName} can't be in future");
        if (model.DOB > DateTime.Now.Date.AddYears(-16))
            return new ValidationResult("You must be 17 years old.");
        if (db < DateTime.Now.Date)
            return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
        return ValidationResult.Success;
    }
}

but this attribute is dependent on my "FormModel" class which is my domain model class.

 public class FormModel
{
    [Required, Display(Name = "Date of Birth")]
    [ValidAge]
    [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime DOB { get; set; }
}

I want this attribute not to depend on "FormModel" class as shown here.So can I somehow get the instance of the model on which I am using this attribute without having to hardcode model's name here ?

1 Answer 1

1

Here are two simple ways without hardcoding model's name like below:

1.The first way:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var model = (DateTime)value;
        var db = model.AddYears(100);
        if (model == null)
            throw new ArgumentException("Attribute not applied on Model");
        if (model > DateTime.Now.Date)
            return new ValidationResult($"{validationContext.DisplayName} can't be in future");
        if (model > DateTime.Now.Date.AddYears(-16))
            return new ValidationResult("You must be 17 years old.");
        if (db < DateTime.Now.Date)
            return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
        return ValidationResult.Success;
    }

2.The second way:

public class FormModel: IValidatableObject
{
    [Required, Display(Name = "Date of Birth")]
    [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime DOB { get; set; }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var data = DOB.AddYears(100);
        if (DOB> DateTime.Now.Date)
        {
            yield return new ValidationResult("Date of Birth can't be in future");
            yield break;
        }
        if (DOB> DateTime.Now.Date.AddYears(-16))
        {
            yield return new ValidationResult("You must be 17 years old.");
            yield break;
        }
        if (data < DateTime.Now.Date)
        {
            yield return new ValidationResult("We rescept you but we cannot accept this date. over 100 years old.");
            yield break;
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

...thanks..It worked...I used the first option you provided. but on a side note...I think this will work only for the datetime properties...if we have to work on other types of model properties then we have to find some other way out as this is specific to datetime property. isnt it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.