Is there any default validation for MVC 5 where I can set min and max value of date?
In my model i want date validation
public class MyClass
There is no need to disable jQuery date validation (and that is likely to cause other issues). You just need to override the range
method of the $.validator
.
By default, it works with numeric values (and then falls back to a string comparison), so you can add the following script (after jquery.validate.js
and jquery.validate.unobtrusive.js
, but not wrapped in $(document).ready
$.validator.methods.range = function(value, element, param) {
if ($(element).attr('data-val-date')) {
var min = $(element).attr('data-val-range-min');
var max = $(element).attr('data-val-range-max');
var date = new Date(value).getTime();
var minDate = new Date(min).getTime();
var maxDate = new Date(max).getTime();
return this.optional(element) || (date >= minDate && date <= maxDate);
}
// use the default method
return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
};
Then you can use the RangeAttribute
on your property
[Range(typeof(DateTime), "1/1/1966", "1/1/2020")]
public DateTime Date { get; set; }
Normally I use this solution when I want to validate something in the server. I know that you can rely on the Validation Model that MVC uses, but when I do the validations, I am trying to use a separate project in case I need to make unit test for them. Lets say you have two applications, one Desktop and one Web, then both can share the ValidationProject instead of repeating the code in both application for the same "View"/"Screen". The idea here is isolate the Validation Project as an independent project of your solution.
So you can download FluentValidation project from NuGet, FluentValidation uses Rules inside the constructor, you can see the documentation here https://github.com/JeremySkinner/FluentValidation/wiki
Your Date rule can be used ont this way for example, there you can put rules for your min value and your max value also:
public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(customer => customer.startDate)
.NotNull()
.WithMessage("You should select a start date")
.Must(d => d.HasValue && d.Value <= DateTime.Today)
.WithMessage("The start date should not be greather than current month/year");
}
Now inside your controller
[HttpPost]
public ActionResult Index(Customer c)
{
if(ModelState.IsValid)
{
var validator= new CustomerValidator();
var valResult = validator.Validate(c);
if (valResult.Errors.Count != 0)
{
valResult.Errors.ForEach(x => ModelState.AddModelError(x.PropertyName, x.ErrorMessage));
return View(vm);
}
//Your code here
}
}
I think just adding the attribute "Range" will work
[Range(typeof(DateTime), "01/01/1900", "06/06/2079", ErrorMessageResourceType = typeof(Resources.Patient), ErrorMessageResourceName = "DateOfBirth_Range")]
I'd do this with the IValidatableObject
interface from System.ComponentModel.DataAnnotations, which allows you to add extra validation rules where you can do a lot more checking. Add the interface to your class, and then implement the Validate
method, where you can compare the StartDateTime against the current date/time, and also compare the EndDateTime with the StartDateTime, e.g.
public class MyClass : IValidatableObject
{
[Required(ErrorMessage="Start date and time cannot be empty")]
//validate:Must be greater than current date
[DataType(DataType.DateTime)]
public DateTime StartDateTime { get; set; }
[Required(ErrorMessage="End date and time cannot be empty")]
//validate:must be greater than StartDate
[DataType(DataType.DateTime)]
public DateTime EndDateTime { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> results = new List<ValidationResult>();
if (StartDateTime < DateTime.Now)
{
results.Add(new ValidationResult("Start date and time must be greater than current time", new []{"StartDateTime"}));
}
if (EndDateTime <= StartDateTime)
{
results.Add(new ValidationResult("EndDateTime must be greater that StartDateTime", new [] {"EndDateTime"}));
}
return results;
}
}
The only potential drawback to this is that Validate
runs server-side, not in jQuery validation.