There is no explicit need of using only ErrorMessage
property to set error text. You can introduce additional properties indicate whether it's needed to check if dates are equal
public string ErrorMessage2 { get; set; }
protected override ValidationResult IsValid(object startTime, ValidationContext validationContext)
{
var endTimePropertyValue = validationContext.ObjectType.GetProperty(EndTimePropertyName)
.GetValue(validationContext.ObjectInstance);
if (startTime != null && startTime is DateTime
& endTimePropertyValue != null && endTimePropertyValue is DateTime)
{
DateTime startDateTime = (DateTime)startTime;
DateTime endDateTime = (DateTime)endTimePropertyValue;
//if second error message is not empty we check if date are the same
bool checkIfEqual = !string.IsNullOrEmpty(ErrorMessage2);
if (checkIfEqual && startDateTime == endDateTime)
{
return new ValidationResult(ErrorMessage2);
}
else if (startDateTime > endDateTime)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
Or you can discard ErrorMessage
at all and use hardcoded strings
private const string StartDateBefore = "StartTime should before than EndTime and EndTime2";
private const string StartDateEqual = "StartTime is equal to EndTime";
public bool CheckIfEqual { get; set; }
protected override ValidationResult IsValid(object startTime, ValidationContext validationContext)
{
var endTimePropertyValue = validationContext.ObjectType.GetProperty(EndTimePropertyName)
.GetValue(validationContext.ObjectInstance);
if (startTime != null && startTime is DateTime
& endTimePropertyValue != null && endTimePropertyValue is DateTime)
{
DateTime startDateTime = (DateTime)startTime;
DateTime endDateTime = (DateTime)endTimePropertyValue;
if (CheckIfEqual && startDateTime == endDateTime)
{
return new ValidationResult(StartDateEqual); //error message when dates are equal
}
else if (startDateTime > endDateTime)
{
return new ValidationResult(StartDateBefore); //error message when start date is after enddate
}
}
return ValidationResult.Success;
}
Usage
[SomeValidation(nameof(EndDate), CheckIfEqual = true)]
public DateTime StartDate { get; set; }
To make this validation attribute work with client side validation you need to implement IClientModelValidator
interface as it described here.
public void AddValidation(ClientModelValidationContext context)
{
//"beforedate" and "equaldate" will be added as custom validators
//for unobtrusive validation
context.Attributes.Add("data-val-beforedate", StartDateBefore);
if (CheckIfEqual)
context.Attributes.Add("data-val-equaldate", StartDateEqual);
}
With this code implemented input
will contain additional attributes with respective error messages. Now we need to implement custom validators in javascript and copy validation logic from C#
code
//add "beforedate" custom validator
$.validator.addMethod("beforedate", function (value, element, parameters) {
var startDate = new Date(value);
var endDate = new Date($("#EndDate").val());
//if condition is true then value considered valid
return endDate >= startDate;
});
//add unobtrusive adapter to run "beforedate" validation
$.validator.unobtrusive.adapters.add("beforedate", [], function (options) {
options.rules.beforedate = {};
options.messages["beforedate"] = options.message; //save error message passed from C#
});
$.validator.addMethod("equaldate", function (value, element, parameters) {
var startDate = new Date(value);
var endDate = new Date($("#EndDate").val());
return endDate.getTime() != startDate.getTime();
});
$.validator.unobtrusive.adapters.add("equaldate", [], function (options) {
options.rules.equaldate = {};
options.messages["equaldate"] = options.message;
});