Żaden z przepisów LessThanOrEqualTo
lub GreaterThanOrEqualTo
są obsługiwane przez walidacji po stronie klienta, jak wyjaśniono w documentation.
To oznacza, że jeśli chcesz mieć sprawdzania poprawności po stronie klienta dla nich będzie trzeba napisać niestandardowy FluentValidationPropertyValidator
i wdrożenie metody GetClientValidationRules
który pozwoli Ci zarejestrować kartę niestandardową i wdrożenia logiki sprawdzania poprawności po stronie klienta za to w javascript .
Jeśli jesteś zainteresowany tym, jak można to osiągnąć, po prostu zadzwoń do mnie, a podam przykład.
UPDATE:
Jako wniosek, postaram się pokazać przykład, jak można zaimplementować sprawdzanie poprawności po stronie klienta korzystającego dla reguły LessThanOrEqualTo
. Jest to tylko szczególny przypadek z nie-nullowanymi datami. Pisanie takiego niestandardowego walidatora po stronie klienta dla wszystkich możliwych przypadków jest oczywiście możliwe, ale będzie wymagało znacznie więcej wysiłku.
Więc zaczynamy z widokiem modelu i odpowiedniego walidator:
[Validator(typeof(MyViewModelValidator))]
public class MyViewModel
{
[Display(Name = "Start date")]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime StartDate { get; set; }
public DateTime DateToCompareAgainst { get; set; }
}
public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
public MyViewModelValidator()
{
RuleFor(x => x.StartDate)
.LessThanOrEqualTo(x => x.DateToCompareAgainst)
.WithMessage("Invalid start date");
}
}
Następnie kontroler:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
StartDate = DateTime.Now.AddDays(2),
DateToCompareAgainst = DateTime.Now
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
i widok:
@model MyViewModel
@using (Html.BeginForm())
{
@Html.Hidden("DateToCompareAgainst", Model.DateToCompareAgainst.ToString("yyyy-MM-dd"))
@Html.LabelFor(x => x.StartDate)
@Html.EditorFor(x => x.StartDate)
@Html.ValidationMessageFor(x => x.StartDate)
<button type="submit">OK</button>
}
Wszystko to jest standard rzeczy jak dotąd. Będzie działać, ale bez sprawdzania poprawności klienta.
Pierwszym krokiem jest napisanie FluentValidationPropertyValidator
:
public class LessThanOrEqualToFluentValidationPropertyValidator : FluentValidationPropertyValidator
{
public LessThanOrEqualToFluentValidationPropertyValidator(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 LessThanOrEqualValidator;
var errorMessage = new MessageFormatter()
.AppendPropertyName(this.Rule.GetDisplayName())
.BuildMessage(validator.ErrorMessageSource.GetString());
var rule = new ModelClientValidationRule
{
ErrorMessage = errorMessage,
ValidationType = "lessthanorequaldate"
};
rule.ValidationParameters["other"] = CompareAttribute.FormatPropertyForClientValidation(validator.MemberToCompare.Name);
yield return rule;
}
}
który zostanie zarejestrowany w Application_Start
podczas konfigurowania naszego dostawcy FluentValidation:
FluentValidationModelValidatorProvider.Configure(x =>
{
x.Add(typeof(LessThanOrEqualValidator), (metadata, context, rule, validator) => new LessThanOrEqualToFluentValidationPropertyValidator(metadata, context, rule, validator));
});
a ostatni bit jest adapter zwyczaj na kliencie . Więc dodajemy oczywiście 2 skrypty do naszej strony, aby umożliwić dyskretne walidacji po stronie klienta:
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
i zasilacz niestandardowe:
(function ($) {
$.validator.unobtrusive.adapters.add('lessthanorequaldate', ['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['lessthanorequaldate'] = element;
if (options.message != null) {
options.messages['lessthanorequaldate'] = options.message;
}
});
$.validator.addMethod('lessthanorequaldate', function (value, element, params) {
var parseDate = function (date) {
var m = date.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
return m ? new Date(parseInt(m[1]), parseInt(m[2]) - 1, parseInt(m[3])) : null;
};
var date = parseDate(value);
var dateToCompareAgainst = parseDate($(params).val());
if (isNaN(date.getTime()) || isNaN(dateToCompareAgainst.getTime())) {
return false;
}
return date <= dateToCompareAgainst;
});
})(jQuery);
Czy jesteś pewien, że pierwsze prace? 'LessThanOrEqualTo' nie jest jedną z zasad wymienionych w [dokumentacja] (http://fluentvalidation.codeplex.com/wikipage?title=mvc&referringTitle=Documentation) jako obsługiwanych przez walidację klienta. Którą wersję FV używasz? –
o człowieku !! to było "LessThanOrEqualTo" czy jest jakaś praca nad tym? – iwayneo