我正在尝试验证如果使用FluentValidation在客户端上检查一个复选框.我无法理解我的生活.
可以使用不显眼的验证来完成吗?
解决方法
我们假设你有以下模型:
[Validator(typeof(MyviewmodelValidator))] public class Myviewmodel { public bool IsChecked { get; set; } }
与以下验证器:
public class MyviewmodelValidator : AbstractValidator<Myviewmodel> { public MyviewmodelValidator() { RuleFor(x => x.IsChecked).Equal(true).WithMessage("Please check this checkBox"); } }
和控制器:
public class HomeController : Controller { public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(Myviewmodel model) { return View(model); } }
具有相应的看法:
@model Myviewmodel @using (Html.BeginForm()) { @Html.LabelFor(x => x.IsChecked) @Html.CheckBoxFor(x => x.IsChecked) @Html.ValidationMessageFor(x => x.IsChecked) <button type="submit">OK</button> }
在Global.asax中,您已经注册了流畅的验证模型验证器提供程序:
FluentValidationModelValidatorProvider.Configure();
到目前为止,我们的服务器端验证正常运行.那很好.这总是我们必须设置的第一部分.我已经看到人们太多地关注客户端验证,他们忘记了服务器端的验证,当你禁用javascript(或者甚至如果你用恶意的用户绊倒的话),那么糟糕的事情就会发生.
到目前为止,我们有信心,因为我们知道,即使在客户端弄坏了某些东西,我们的域也受到服务器端验证的保护.
所以现在我们来看看客户端的验证.开箱即用FluentValidation.NET支持EqualTo验证器的自动客户端验证,但与另一个等价于[比较]数据注释的属性值进行比较时.
但在我们的例子中,我们正在比较一个固定值.所以我们没有得到客户端的vaildation开箱即用.当我们没有开箱即用时,我们需要把它放在盒子里.
所以我们首先定义一个自定义FluentValidationPropertyValidator:
public class EqualToValueFluentValidationPropertyValidator : FluentValidationPropertyValidator { public EqualToValueFluentValidationPropertyValidator(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 = (EqualValidator)Validator; var errorMessage = new MessageFormatter() .AppendPropertyName(Rule.GetDisplayName()) .AppendArgument("ValueToCompare",validator.ValueToCompare) .BuildMessage(validator.ErrorMessageSource.GetString()); var rule = new ModelClientValidationRule(); rule.ErrorMessage = errorMessage; rule.ValidationType = "equaltovalue"; rule.ValidationParameters["valuetocompare"] = validator.ValueToCompare; yield return rule; } }
我们将在Application_Start中注册:
FluentValidationModelValidatorProvider.Configure(provider => { provider.AddImplicitrequiredValidator = false; provider.Add(typeof(EqualValidator),(Metadata,context,description,validator) => new EqualToValueFluentValidationPropertyValidator(Metadata,validator)); });
到目前为止,我们已将自定义FluentValidationPropertyValidator与EqualValidator相关联.
最后一部分是写一个自定义适配器:
(function ($) { $.validator.unobtrusive.adapters.add('equaltovalue',['valuetocompare'],function (options) { options.rules['equaltovalue'] = options.params; if (options.message != null) { options.messages['equaltovalue'] = options.message; } }); $.validator.addMethod('equaltovalue',function (value,element,params) { if ($(element).is(':checkBox')) { if ($(element).is(':checked')) { return value.toLowerCase() === 'true'; } else { return value.toLowerCase() === 'false'; } } return params.valuetocompare.toLowerCase() === value.toLowerCase(); }); })(jQuery);
这几乎是这样的.剩下的就是包括客户端脚本:
<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> <script src="@Url.Content("~/Scripts/customadapter.js")" type="text/javascript"></script>