C# 使用 fluentvalidation 和 asp.net mvc LessThanOrEqualTo 不触发不显眼的客户端验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9380010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
unobtrusive client validation using fluentvalidation and asp.net mvc LessThanOrEqualTo not firing
提问by
I have the following rules
我有以下规则
the 1st does work using unobtrusive, client side validation, the second does not
第一个确实使用不显眼的客户端验证工作,第二个没有
any ideas why?
任何想法为什么?
RuleFor(x => x.StartDate)
.LessThanOrEqualTo(x => x.EndDate.Value)
.WithLocalizedMessage(() => CommonRes.Less_Than_Or_Equal_To, filters => CommonRes.Start_Date, filters => CommonRes.End_Date);
RuleFor(x => x.StartDate)
.GreaterThanOrEqualTo(x => x.AbsoluteStartDate)
.LessThanOrEqualTo(x => x.AbsoluteEndDate)
.WithLocalizedMessage(() => CommonRes.Between, filters => CommonRes.Start_Date, filters => filters.AbsoluteStartDate, filters => filters.AbsoluteEndDate);
采纳答案by Darin Dimitrov
Neither of the LessThanOrEqualToor GreaterThanOrEqualTorules are supported by client side validation as explained in the documentation.
既不的LessThanOrEqualTo或GreaterThanOrEqualTo规则由客户端验证支持作为中说明的文档。
This means that if you want to have client side validation for them you will need to write a custom FluentValidationPropertyValidatorand implement the GetClientValidationRulesmethod which will allow you to register a custom adapter and implement the client side validation logic for it in javascript.
这意味着如果您想为它们进行客户端验证,您将需要编写一个自定义FluentValidationPropertyValidator并实现GetClientValidationRules允许您注册自定义适配器并在 javascript 中为其实现客户端验证逻辑的方法。
If you are interested on how this could be achieved just ping me and I will provide an example.
如果您对如何实现这一点感兴趣,请 ping 我,我将提供一个示例。
Update
更新
As request, I will try to show an example of how one could implement custom client side validation for the LessThanOrEqualTorule. It is only a particular case with non-nullable dates. Writing such custom client side validator for all the possible case is of course possible but it will require significantly more efforts.
作为请求,我将尝试展示一个示例,说明如何为LessThanOrEqualTo规则实现自定义客户端验证。这只是具有不可为空日期的特殊情况。为所有可能的情况编写这样的自定义客户端验证器当然是可能的,但这需要付出更多的努力。
So we start with a view model and a corresponding validator:
所以我们从一个视图模型和一个相应的验证器开始:
[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");
}
}
Then a controller:
然后是一个控制器:
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);
}
}
and a view:
和一个观点:
@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>
}
All this is standard stuff so far. It will work but without client validation.
到目前为止,所有这些都是标准的东西。它可以工作,但无需客户端验证。
The first step is to write the FluentValidationPropertyValidator:
第一步是编写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;
}
}
which will be registered in Application_Startwhen configuring our FluentValidation provider:
这将在Application_Start配置我们的 FluentValidation 提供程序时注册:
FluentValidationModelValidatorProvider.Configure(x =>
{
x.Add(typeof(LessThanOrEqualValidator), (metadata, context, rule, validator) => new LessThanOrEqualToFluentValidationPropertyValidator(metadata, context, rule, validator));
});
And the last bit is the custom adapter on the client. So we add of course the 2 scripts to our page in order to enable unobtrusive client side validation:
最后一点是客户端上的自定义适配器。因此,我们当然将 2 个脚本添加到我们的页面,以启用不显眼的客户端验证:
<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>
and the custom adapter:
和自定义适配器:
(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);
回答by ROFLwTIME
Darin's example has some obsolete stuff in it, so here is a more updated example that I have that does number comparisons. You can easily tweak it for date comparisons though:
Darin 的例子中有一些过时的东西,所以这里有一个更新的例子,我有一个进行数字比较的例子。不过,您可以轻松调整它以进行日期比较:
Javascript:
Javascript:
(function ($)
{
$.validator.addMethod("lessthanorequal", function(value, element, param)
{
return this.optional(element) || parseFloat(value) <= parseFloat(param);
}, "Must be less than");
$.validator.unobtrusive.adapters.add("lessthanorequal", ["field"], function (options)
{
options.rules["lessthanorequal"] = options.params.field;
if (options.message) options.messages["lessthanorequal"] = options.message;
});
})(jQuery);
C#
C#
public class LessThanOrEqualPropertyValidator : FluentValidationPropertyValidator
{
public LessThanOrEqualPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
: base(metadata, controllerContext, rule, validator)
{
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
if (!ShouldGenerateClientSideRules()) yield break;
var formatter = new MessageFormatter().AppendPropertyName(Rule.PropertyName);
string message = formatter.BuildMessage(Validator.ErrorMessageSource.GetString());
var rule = new ModelClientValidationRule
{
ValidationType = "lessthanorequal",
ErrorMessage = message
};
rule.ValidationParameters["field"] = ((LessThanOrEqualValidator)Validator).ValueToCompare;
yield return rule;
}
}
Global.asax Application_Start:
Global.asax Application_Start:
FluentValidation.Mvc.FluentValidationModelValidatorProvider.Configure(x =>
{
x.Add(typeof(LessThanOrEqualValidator), (metadata, context, description, validator) => new LessThanOrEqualPropertyValidator(metadata, context, description, validator));
});
So now any number rule that uses LessThanOrEqual will be validated client side.
所以现在任何使用 LessThanOrEqual 的数字规则都将在客户端进行验证。
回答by ndequeker
LessThanOrEqualToand GreaterThanOrEqualTodo not support clientside validation out of the box.
LessThanOrEqualTo并且GreaterThanOrEqualTo不支持开箱即用的客户端验证。
However, InclusiveBetweenis supported. So you could use InclusiveBetween.
但是,InclusiveBetween是支持的。所以你可以使用InclusiveBetween.
Example
例子
RuleFor(x => x.StartDate)
.InclusiveBetween(x.AbsoluteStartDate, x.AbsoluteEndDate)
See the documentation for mor information about supported clientside methods.
有关受支持的客户端方法的更多信息,请参阅文档。

