ModelState["Prop"]).Errors 中的 Fluent Validation 重复错误
Fluent Validation Duplicate Errors in ModelState["Prop"]).Errors
当我检查我的 ModelState["Email"].Errors
时,我发现相同的验证错误重复了 3 次,对于我的所有模型正好重复了 3 次,我的模型包含超过 3 个属性。
我想知道为什么规则被执行了三次。
我正在使用 MVC 5,以及 Autofac。我找不到错误!
没有错误,但如果每个 属性 都被验证 3 次,我担心性能,有些验证很复杂,有时会连接到数据库。
下面是我用来注册 Validators
、Fluent Validation
和 Autofac
.
的代码
builder.RegisterAssemblyTypes(System.Reflection.Assembly.Load("MyAssembly"))
.Where(t => t.Name.EndsWith("Validator"))
.AsImplementedInterfaces()
.InstancePerRequest();
builder.RegisterType<FluentValidationModelValidatorProvider>().As<ModelValidatorProvider>();
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance();
Container = builder.Build();// Build !
// FluentValidation wire up to MVC
var fluentValidationModelValidatorProvider = new fluentValidationModelValidatorProvider()
{
AddImplicitRequiredValidator = false,
ValidatorFactory = new AutofacValidatorFactory()
};
//fluentValidationModelValidatorProvider.AddImplicitRequiredValidator = false;
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(Container);
模型看起来像这样:
public class ContactInfoDTO
{
public int ID { get; set; }
public string Email { get; set; }
public string Email2 { get; set; }
public string PhoneNumber { get; set; }
public string PhoneNumber2 { get; set; }
public string EmergencyNumber { get; set; }
public string EmergencyPersonName { get; set; }
public ContactInfoDTO()
{
}
}
这是您应该如何使用 Fluent 验证:
using FluentValidation;
public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(customer => customer.Surname).NotEmpty();
RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
RuleFor(customer => customer.Address).Length(20, 250);
RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}
private bool BeAValidPostcode(string postcode) {
// custom postcode validating logic goes here
}
}
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
你应该为你的模型创建一个验证器,这样你就可以控制当你验证你的对象时发生的事情。
感谢大家的支持。
感谢 FluentValidation 的所有者 Jeremy Skinner 先生对其进行了调查,link 得到了以下解决方案。
毕竟是我的错:)
https://github.com/JeremySkinner/FluentValidation/issues/362
当我检查我的 ModelState["Email"].Errors
时,我发现相同的验证错误重复了 3 次,对于我的所有模型正好重复了 3 次,我的模型包含超过 3 个属性。
我想知道为什么规则被执行了三次。
我正在使用 MVC 5,以及 Autofac。我找不到错误!
没有错误,但如果每个 属性 都被验证 3 次,我担心性能,有些验证很复杂,有时会连接到数据库。
下面是我用来注册 Validators
、Fluent Validation
和 Autofac
.
builder.RegisterAssemblyTypes(System.Reflection.Assembly.Load("MyAssembly"))
.Where(t => t.Name.EndsWith("Validator"))
.AsImplementedInterfaces()
.InstancePerRequest();
builder.RegisterType<FluentValidationModelValidatorProvider>().As<ModelValidatorProvider>();
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance();
Container = builder.Build();// Build !
// FluentValidation wire up to MVC
var fluentValidationModelValidatorProvider = new fluentValidationModelValidatorProvider()
{
AddImplicitRequiredValidator = false,
ValidatorFactory = new AutofacValidatorFactory()
};
//fluentValidationModelValidatorProvider.AddImplicitRequiredValidator = false;
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(Container);
模型看起来像这样:
public class ContactInfoDTO
{
public int ID { get; set; }
public string Email { get; set; }
public string Email2 { get; set; }
public string PhoneNumber { get; set; }
public string PhoneNumber2 { get; set; }
public string EmergencyNumber { get; set; }
public string EmergencyPersonName { get; set; }
public ContactInfoDTO()
{
}
}
这是您应该如何使用 Fluent 验证:
using FluentValidation;
public class CustomerValidator: AbstractValidator<Customer> {
public CustomerValidator() {
RuleFor(customer => customer.Surname).NotEmpty();
RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
RuleFor(customer => customer.Address).Length(20, 250);
RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
}
private bool BeAValidPostcode(string postcode) {
// custom postcode validating logic goes here
}
}
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
你应该为你的模型创建一个验证器,这样你就可以控制当你验证你的对象时发生的事情。
感谢大家的支持。 感谢 FluentValidation 的所有者 Jeremy Skinner 先生对其进行了调查,link 得到了以下解决方案。 毕竟是我的错:)
https://github.com/JeremySkinner/FluentValidation/issues/362