Apply custom validation in Asp.Net MVC Model throw

2019-09-20 23:42发布

So I have this issue.

I have 2 field is Date of birth and Start working date.I want to apply custom validation following this if

start working date - date of birth is >= 22

then is valid.So here is my code

[AttributeUsage(AttributeTargets.Property)]
    public class MiniumAgeAttribute:ValidationAttribute
    {
        private DateTime dob { get; set; }
        private DateTime startDate { get; set; }
        public MiniumAgeAttribute(DateTime DOB, DateTime StartDate)
        {
            dob = DOB;
            startDate = StartDate;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            int age;
            age = startDate.Year - dob.Year;
            if (age >= 22)
            {
                return ValidationResult.Success;
            }
            else
            {
                return new ValidationResult("Age is required to be 22 or more");
            }

        }
}

But when I apply my validation rules in model I get this error

enter image description here

So how can I fix it. Kind Regard.

1条回答
仙女界的扛把子
2楼-- · 2019-09-21 00:30

Attributes are metadata and must be known at compile time and therefore must be constants. You cannot pass the value of a property which is not know until runtime. Instead, you pass the name of the property and use reflection to get the value of the property.

Typically you decorate a model property with the attribute so its only necessary to pass the name of the other property, not both dob and startDate. In additional your attribute allows no flexibility because you have hard coded the age in the method, and that value should also be passed to the method so that it can be used as (say)

[MiminumAge(22, "DateOfBirth")] // or [MiminumAge(18, "DateOfBirth")]
public DateTime StartDate { get; set; }
public DateTime DateOfBirth { get; set; }

You logic is also incorrect because startDate.Year - dob.Year does not take into account the day and month values of the dates.

Your attribute should be

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class MiminumAgeAttribute : ValidationAttribute
{
    private const string _DefaultErrorMessage = "You must be at least {0} years of age.";
    private readonly string _DOBPropertyName;
    private readonly int _MinimumAge;

    public MiminumAgeAttribute (string dobPropertyName, int minimumAge)
    {
        if (string.IsNullOrEmpty(dobPropertyName))
        {
            throw new ArgumentNullException("propertyName");
        }
        _DOBPropertyName= dobPropertyName;
        _MinimumAge = minimumAge;
        ErrorMessage = _DefaultErrorMessage;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        DatetTime startDate;
        DateTime dateOfBirth;
        bool isDateValid = DateTime.TryParse((string)value, out startDate);
        var dobPropertyName = validationContext.ObjectInstance.GetType().GetProperty(_DOBPropertyName);
        var dobPropertyValue = dobPropertyName.GetValue(validationContext.ObjectInstance, null);
        isDOBValid = DateTime.TryParse((string)dobPropertyValue, out dateOfBirth);
        if (isDateValid && isDOBValid)
        {
            int age = startDate.Year - dateOfBirth.Year;
            if (dateOfBirth > startDate.AddYears(-age))
            {
                age--;
            }
            if (age < _MinimumAge)
            {
                return new ValidationResult(string.Format(ErrorMessageString, _MinimumAge));
            }
        }
        return ValidationResult.Success;
    }
}

You can also enhance this further by implementing IClientValidatable and adding scripts to the view to give you client side validation using the jquery.validate.js and jquery.validate.unobtrusive.js plugins. For more detail, refer THE COMPLETE GUIDE TO VALIDATION IN ASP.NET MVC 3 - PART 2

查看更多
登录 后发表回答