I have a simple input model for my blazor server side component. I want to use the build in validation for two DateTime properties.
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }
How can I only accept ToDate > FromDate?
CodePudding user response:
Solution using custom ValidationAttribute
:
public class DateMustBeAfterAttribute : ValidationAttribute
{
public DateMustBeAfterAttribute(string propertyName)
=> PropertyName = propertyName;
public string PropertyName { get; }
public string GetErrorMessage() =>
$"Date must be after {PropertyName}.";
protected override ValidationResult? IsValid(
object? value, ValidationContext validationContext)
{
var model = (DateTimeModel)validationContext.ObjectInstance;
if ((DateTime?)value < (DateTime?)model.GetType().GetProperty(PropertyName)?.GetValue(model, null))
{
return new ValidationResult(GetErrorMessage());
}
return ValidationResult.Success;
}
}
Usage:
public class DateTimeModel
{
[Required]
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[Required]
[DateMustBeAfter(nameof(FromDate))]
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }
}
Solution using IValidatableObject
:
To do more complex validation checks, your model can inherit from IValidatableObject
interface and implement the Validate
method:
public class ExampleModel : IValidatableObject
{
[DataType(DataType.Date)]
public DateTime? FromDate { get; set; }
[DataType(DataType.Date)]
public DateTime? ToDate { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (ToDate < FromDate)
{
yield return new ValidationResult("ToDate must be after FromDate", new[] { nameof(ToDate) });
}
}
}
CodePudding user response:
I am afraid you cannot achieve this using the built-in validation. You need to create your own validation component. See for more info here and here.