C# FluentValidation中每个自定义规则的客户端验证的最佳方法
我正在Asp.NETMVC4应用程序中使用FluentValidation。我已经知道一些规则会自动为jQuery验证库生成属性。这个脚本库已经知道它必须检查什么,例如在C# FluentValidation中每个自定义规则的客户端验证的最佳方法,c#,asp.net-mvc,asp.net-mvc-4,unobtrusive-validation,fluentvalidation,C#,Asp.net Mvc,Asp.net Mvc 4,Unobtrusive Validation,Fluentvalidation,我正在Asp.NETMVC4应用程序中使用FluentValidation。我已经知道一些规则会自动为jQuery验证库生成属性。这个脚本库已经知道它必须检查什么,例如在需要数据规则、数据规则范围等情况下 我知道FluentValidation中有一些函数,但这些函数不包括在客户端。例如:.Equal(true)。 我已经检查了答案,并且没有任何问题地实现了它 但是,我不希望总是创建从FluentValidationPropertyValidator继承的新类。我们必须像global.asax中
需要数据规则
、数据规则范围
等情况下
我知道FluentValidation中有一些函数,但这些函数不包括在客户端。例如:.Equal(true)
。
我已经检查了答案,并且没有任何问题地实现了它
但是,我不希望总是创建从FluentValidationPropertyValidator
继承的新类。我们必须像global.asax中那样将其添加到提供程序中:
provider.Add(typeof(EqualValidator), (metadata, context, description, validator) => new EqualToValueClientRule(metadata, context, description, validator));
在这种情况下,EqualValidator
已在FluentValidation中实现。但是,如果我们创建了一个带有When
关键字的验证器,该怎么办呢。例如,我有:
this.RuleFor(phone => phone.Digits)
.Length(7)
.When(phone => phone.PrefixId == 2)
.WithMessage("Numbers in 2nd city must contain 7 characters");
this.RuleFor(phone => phone.Digits)
.Length(7)
.When(phone => phone.PrefixId > 64)
.WithMessage("Mobile number must contain 7 characters");
this.RuleFor(phone => phone.Digits)
.Length(5)
.When(phone => phone.PrefixId != 2)
.WithMessage("Numbers in other cities must contain 5 characters")
当然,我可以用jQuery/JavaScript检查这一点,没有任何问题。但是,这种方法并不好。在其他情况下,您必须编写大量代码来在客户端生成自定义属性,并向适配器添加新函数。或者,只使用jQuery/JavaScript?还是别的什么?也许我们可以将JavaScript函数名添加到FluentValidationPropertyValidator
你推荐我什么?我想了很多,发现最好的方法是创建新的验证器,该验证器继承自
PropertyValidator
,并实现IClientValidable
接口。因此,它将包含服务器端验证,并按照我们的意愿生成不引人注目的属性。然后我们必须在不显眼的库中注册这个新的验证器
例如,我问题中规则的验证器将是:
public class MustFitToPhonePrefix<TModel, TProperty> : PropertyValidator, IClientValidatable
{
private string dependencyElement;
public MustFitToPhonePrefix(Expression<Func<TModel, TProperty>> expression)
: base("Format is wrong")
{
dependencyElement = (expression.Body as MemberExpression).Member.Name;
}
// Server side validation
protected override bool IsValid(PropertyValidatorContext context)
{
// Instance of the class which contains property which must be validated
var phone = context.ParentContext.InstanceToValidate as PhoneDetail;
...
// Custom logic
...
// Everything is valid
return true;
}
// Generate jquery unobtrusive attributes
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = this.ErrorMessageSource.GetString(), // default error message
ValidationType = "fittoprefix" // name of the validatoin which will be used inside unobtrusive library
};
rule.ValidationParameters["prefixelement"] = dependencyElement; // html element which includes prefix information
yield return rule;
}
最后,我们可以设置验证器:
// Will check if the phone number fits to phone prefix
$.validator.addMethod('fittoprefix', function (value, element, params) {
var parent = getParentPropertyName(element);
var prefixId = $("#{0}_{1}".format(parent, params.prefixelement)).val();
var digitsLength = $(element).val().Length;
...
// Custom logic
...
return true;
});
// Registration - Will check if the phone number fits to phone prefix
$.validator.unobtrusive.adapters.add('fittoprefix', ['prefixelement'], function (options) {
options.rules['fittoprefix'] = options.params;
if (options.message != null) {
options.messages['fittoprefix'] = options.message;
}
});
this.RuleFor(m => m.Digits)
.SetValidator(new MustFitToPhonePrefix<PhoneDetail, int>(m => m.PrefixId));
this.RuleFor(m=>m.Digits)
.SetValidator(新MustFitToPhonePrefix(m=>m.PrefixId));
我认为最好的方法是创建PropertyValidator类,该类在服务器端始终有效,注册javascript函数名,该函数名将在客户端执行。@EvgenyLevin我已经做过了。此外,我的验证器还实现了iclientvalidable
。它将在客户端创建验证属性。所以,我可以很容易地在其他项目中使用这个验证器。是的,你的验证器很好,可以作为电话验证器重用,但我的想法是创建“假”验证器,只在特殊属性中注册客户端函数,适配器,调用js函数,以及使用规则生成器链的扩展。然后调用将如下所示:RuleFor(phone=>phone.Digits).Length(7.When(…).WithMessage(“…”).Length(5.When(…).WithMessage(“…”).ClientSideRule(“allPhoneValidationLogicWithWhenConditionsFunction”)代码>@EvgenyLevin我知道了。但是,我将在哪里创建客户端属性?