.NET MVC Custom Date Validator
Solution 1
public sealed class DateStartAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
DateTime dateStart = (DateTime)value;
// Meeting must start in the future time.
return (dateStart > DateTime.Now);
}
}
public sealed class DateEndAttribute : ValidationAttribute
{
public string DateStartProperty { get; set; }
public override bool IsValid(object value)
{
// Get Value of the DateStart property
string dateStartString = HttpContext.Current.Request[DateStartProperty];
DateTime dateEnd = (DateTime)value;
DateTime dateStart = DateTime.Parse(dateStartString);
// Meeting start time must be before the end time
return dateStart < dateEnd;
}
}
and in your View Model:
[DateStart]
public DateTime StartDate{ get; set; }
[DateEnd(DateStartProperty="StartDate")]
public DateTime EndDate{ get; set; }
In your action, just check that ModelState.IsValid
. That what you're after?
Solution 2
I know this post is older, but, this solution I found is much better.
The accepted solution in this post won't work if the object has a prefix when it is part of a viewmodel.
i.e. the lines
// Get Value of the DateStart property
string dateStartString = HttpContext.Current.Request[DateStartProperty];
A better solution can be found here: ASP .NET MVC 3 Validation using Custom DataAnnotation Attribute:
New DateGreaterThan
attribute:
public sealed class DateGreaterThanAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "'{0}' must be greater than '{1}'";
private string _basePropertyName;
public DateGreaterThanAttribute(string basePropertyName) : base(_defaultErrorMessage)
{
_basePropertyName = basePropertyName;
}
//Override default FormatErrorMessage Method
public override string FormatErrorMessage(string name)
{
return string.Format(_defaultErrorMessage, name, _basePropertyName);
}
//Override IsValid
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//Get PropertyInfo Object
var basePropertyInfo = validationContext.ObjectType.GetProperty(_basePropertyName);
//Get Value of the property
var startDate = (DateTime)basePropertyInfo.GetValue(validationContext.ObjectInstance, null);
var thisDate = (DateTime)value;
//Actual comparision
if (thisDate <= startDate)
{
var message = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(message);
}
//Default return - This means there were no validation error
return null;
}
}
Usage example:
[Required]
[DataType(DataType.DateTime)]
[Display(Name = "StartDate")]
public DateTime StartDate { get; set; }
[Required]
[DataType(DataType.DateTime)]
[Display(Name = "EndDate")]
[DateGreaterThanAttribute("StartDate")]
public DateTime EndDate { get; set; }
MrBliz
Updated on June 01, 2022Comments
-
MrBliz almost 2 years
I'll be tackling writing a custom date validation class tomorrow for a meeting app i'm working on at work that will validate if a given start or end date is A) less than the current date, or B) the start date is greater than the end date of the meeting (or vice versa).
I think this is probably a fairly common requirement. Can anyone point me in the direction of a blog post that might help me out in tackling this problem?
I'm using .net 3.5 so i can't use the new model validator api built into .NET 4. THe project i'm working on is MVC 2.
UPDATE: THe class i'm writing needs to extend the System.ComponentModel.DataAnnotations namespace. In .NET 4 there is a IValidateObject interface that you can implement, that makes this sort of thing an absolute doddle, but sadly i can't use .Net 4. How do i go about doing the same thing in .Net 3.5?
-
MrBliz over 13 yearsHi thanks, after reading you answer i realised i needed to provide my info. Of course the code that you have provided will validate a date, but it wasn't that part of the problem i was stuck on. I needed to know what interfaces to implement to extend the dataannotations namespace. Thanks anyway.
-
MrBliz over 13 yearsIn this case how do i pick up the values for StartDate and EndDate from the model, since they are both user entered values?
-
just.jimmy over 13 yearsChanged my answer. :) So StartDate checks with DateTime.Now. EndDate checks with StartDate which is user entered to make sure it's after the start date.
-
DanO almost 12 yearsDefinitely a better solution! +1 for the helpful link!
-
Azarsa over 9 yearsWhy my dateStartString from current context is null?
-
matty_simms almost 5 yearsHere is the entry from the wayback machine. web.archive.org/web/20150204084444/http://www.a2zdotnet.com/…
-
Chris over 3 yearsWelcome to Stack Overflow. Code dumps without any explanation are rarely helpful. Stack Overflow is about learning, not providing snippets to blindly copy and paste. Please edit your question and explain how it works better than what the OP provided. See How to Answer.