Trick using Greater Then Or Equal To Validator. Works for me.
Global.asax - Application Start Event
FluentValidationModelValidatorProvider.Configure(x =>
{
x.Add(typeof(GreaterThanOrEqualValidator),
(metadata, Context, rule, validator) =>
new LessThanOrEqualToFluentValidationPropertyValidator
(
metadata, Context, rule, validator
)
);
});
Model
[Validator(typeof(MyViewModelValidator))]
public class MyViewModel
{
[Display(Name = "Start date")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime StartDate { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime DateToCompareAgainst { get; set; }
}
Rule
public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
public MyViewModelValidator()
{
RuleFor(x => x.StartDate)
.GreaterThanOrEqualTo(x => x.DateToCompareAgainst)
.WithMessage("Invalid start date");
}
}
FluentValidationPropertyValidator
public class GreaterThenOrEqualTo : FluentValidationPropertyValidator
{
public GreaterThenOrEqualTo(ModelMetadata metadata,
ControllerContext controllerContext,
PropertyRule rule,
IPropertyValidator validator)
: base(metadata, controllerContext, rule, validator)
{
}
public override IEnumerable<ModelClientValidationRule>
GetClientValidationRules()
{
if (!this.ShouldGenerateClientSideRules())
{
yield break;
}
var validator = Validator as GreaterThanOrEqualValidator;
var errorMessage = new MessageFormatter()
.AppendPropertyName(this.Rule.GetDisplayName())
.BuildMessage(validator.ErrorMessageSource.GetString());
var rule = new ModelClientValidationRule{
ErrorMessage = errorMessage,
ValidationType = "greaterthanorequaldate"};
rule.ValidationParameters["other"] =
CompareAttribute.FormatPropertyForClientValidation(
validator.MemberToCompare.Name);
yield return rule;
}
}
Controller Action Method
public ActionResult Index()
{
var model = new MyViewModel
{
StartDate = DateTime.Now.AddDays(2),
DateToCompareAgainst = default(DateTime) //Default Date
};
return View(model);
}
[HttpPost]
public ActionResult Index(Practise.Areas.FluentVal.Models.MyViewModel p)
{
return View(p);
}
View
@using (Html.BeginForm("Index", "Person", FormMethod.Post,
new { id = "FormSubmit" }))
{
@Html.Hidden("DateToCompareAgainst", Model.DateToCompareAgainst);
@Html.LabelFor(x => x.StartDate)
@Html.EditorFor(x => x.StartDate)
@Html.ValidationMessageFor(x => x.StartDate)
<button type="submit">
OK</button>
}
Script
<script src="jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.js" type="text/javascript"></script>
<script type="text/javascript">
(function ($) {
$.validator.unobtrusive.adapters.add('greaterthanorequaldate',
['other'], function (options) {
var getModelPrefix = function (fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
};
var appendModelPrefix = function (value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input[name=" + fullOtherName +
"]")[0];
options.rules['greaterthanorequaldate'] = element;
if (options.message != null) {
options.messages['greaterthanorequaldate'] = options.message;
}
});
$.validator.addMethod('greaterthanorequaldate',
function (value, element, params) {
var date = new Date(value);
var dateToCompareAgainst = new Date($(params).val());
if (isNaN(date.getTime()) || isNaN(dateToCompareAgainst.getTime())) {
return false;
}
return date >= dateToCompareAgainst;
});
})(jQuery);
</script>