ASP .NET MVC 3 Data Annotations GreaterThan LowerThan for DateTime and int

后端 未结 5 2134
执念已碎
执念已碎 2021-02-13 10:19

I would like to know what is the easiest way to have a \"Greater Than\" & \"Lower Than\" validation on a ASP.NET MVC 3 form?

I use unobtrusive JavaScript for client

5条回答
  •  猫巷女王i
    2021-02-13 10:32

    You can simply do this with custom validation.

    [AttributeUsage(AttributeTargets.Property, AllowMultiple=true)]
        public class DateGreaterThanAttribute : ValidationAttribute
        {
            string otherPropertyName;
    
            public DateGreaterThanAttribute(string otherPropertyName, string errorMessage)
                : base(errorMessage)
            {
                this.otherPropertyName = otherPropertyName;
            }
    
            protected override ValidationResult IsValid(object value, ValidationContext validationContext)
            {
                ValidationResult validationResult = ValidationResult.Success;
                try
                {
                    // Using reflection we can get a reference to the other date property, in this example the project start date
                    var otherPropertyInfo = validationContext.ObjectType.GetProperty(this.otherPropertyName);
                    // Let's check that otherProperty is of type DateTime as we expect it to be
                    if (otherPropertyInfo.PropertyType.Equals(new DateTime().GetType()))
                    {
                        DateTime toValidate = (DateTime)value;
                        DateTime referenceProperty = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
                        // if the end date is lower than the start date, than the validationResult will be set to false and return
                        // a properly formatted error message
                        if (toValidate.CompareTo(referenceProperty) < 1)
                        {
                            validationResult = new ValidationResult(ErrorMessageString);
                        }
                    }
                    else
                    {
                        validationResult = new ValidationResult("An error occurred while validating the property. OtherProperty is not of type DateTime");
                    }
                }
                catch (Exception ex)
                {
                    // Do stuff, i.e. log the exception
                    // Let it go through the upper levels, something bad happened
                    throw ex;
                }
    
                return validationResult;
            }
    }
    

    and use it in model like

     [DisplayName("Start date")]
        [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]        
        public DateTime StartDate { get; set; }
    
        [DisplayName("Estimated end date")]
        [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
        [DateGreaterThan("StartDate", "End Date end date must not exceed start date")]
        public DateTime EndDate { get; set; }
    

    This works well with server side validation.For client side validaion you can write the method like GetClientValidationRules like

    public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
            {
                //string errorMessage = this.FormatErrorMessage(metadata.DisplayName);
                string errorMessage = ErrorMessageString;
    
                // The value we set here are needed by the jQuery adapter
                ModelClientValidationRule dateGreaterThanRule = new ModelClientValidationRule();
                dateGreaterThanRule.ErrorMessage = errorMessage;
                dateGreaterThanRule.ValidationType = "dategreaterthan"; // This is the name the jQuery adapter will use
                //"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
                dateGreaterThanRule.ValidationParameters.Add("otherpropertyname", otherPropertyName);
    
                yield return dateGreaterThanRule;
            }
    

    Now simply in view

    $.validator.addMethod("dategreaterthan", function (value, element, params) {
    
        return Date.parse(value) > Date.parse($(params).val());
    });
    $.validator.unobtrusive.adapters.add("dategreaterthan", ["otherpropertyname"], function (options) {
        options.rules["dategreaterthan"] = "#" + options.params.otherpropertyname;
        options.messages["dategreaterthan"] = options.message;
    });
    

    You can find more details in this link

提交回复
热议问题