Bja*_*ðar 12 .net c# fluentvalidation
我可以为对象添加多个验证器吗?例如:
public interface IFoo
{
int Id { get; set; }
string Name { get; set; }
}
public interface IBar
{
string Stuff { get; set; }
}
public class FooValidator : AbstractValidator<IFoo>
{
public FooValidator ()
{
RuleFor(x => x.Id).NotEmpty().GreaterThan(0);
}
}
public class BarValidator : AbstractValidator<IBar>
{
public BarValidator()
{
RuleFor(x => x.Stuff).Length(5, 30);
}
}
public class FooBar : IFoo, IBar
{
public int Id { get; set; }
public string Name { get; set; }
public string Stuff { get; set; }
}
public class FooBarValidator : AbstractValidator<FooBar>
{
public FooBarValidator()
{
RuleFor(x => x)
.SetValidator(new FooValidator())
.SetValidator(new BarValidator());
}
}
Run Code Online (Sandbox Code Playgroud)
运行测试.
FooBarValidator validator = new FooBarValidator();
validator.ShouldHaveValidationErrorFor(x => x.Id, 0);
Run Code Online (Sandbox Code Playgroud)
我得到一个InvalidOperationException:
无法为表达式x => x自动确定属性名称.请通过调用'WithName'指定自定义属性名称.
有没有办法实现这个,或者我试图以一种不打算使用的方式使用FluentValidation?
Eli*_*ert 19
RuleFor正在尝试创建属性级规则.您还可以使用AddRule函数添加通用规则.
使用这个,我创建了一个复合规则的概念证明.它接受一组其他验证器并运行它们.该yield break代码开门见山FluentValidator的DelegateValidator.我不知道该怎么办,所以我从源头抓住了它.我没有追溯它的全部目的,但一切似乎都工作:)
public interface IFoo
{
int Id { get; set; }
string Name { get; set; }
}
public interface IBar
{
string Stuff { get; set; }
}
public class FooValidator : AbstractValidator<IFoo>
{
public FooValidator()
{
RuleFor(x => x.Id).NotEmpty().GreaterThan(0);
}
}
public class BarValidator : AbstractValidator<IBar>
{
public BarValidator()
{
RuleFor(x => x.Stuff).Length(5, 30);
}
}
public class FooBar : IFoo, IBar
{
public int Id { get; set; }
public string Name { get; set; }
public string Stuff { get; set; }
}
public class CompositeValidatorRule : IValidationRule
{
private IValidator[] _validators;
public CompositeValidatorRule(params IValidator[] validators)
{
_validators = validators;
}
#region IValidationRule Members
public string RuleSet
{
get; set;
}
public IEnumerable<ServiceStack.FluentValidation.Results.ValidationFailure> Validate(ValidationContext context)
{
var ret = new List<ServiceStack.FluentValidation.Results.ValidationFailure>();
foreach(var v in _validators)
{
ret.AddRange(v.Validate(context).Errors);
}
return ret;
}
public IEnumerable<ServiceStack.FluentValidation.Validators.IPropertyValidator> Validators
{
get { yield break; }
}
#endregion
}
public class FooBarValidator : AbstractValidator<FooBar>
{
public FooBarValidator()
{
AddRule(new CompositeValidatorRule(new FooValidator(), new BarValidator()));
}
}
Run Code Online (Sandbox Code Playgroud)
[TestMethod]
public void TestValidator()
{
FooBarValidator validator = new FooBarValidator();
var result = validator.Validate(new FooBar());
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助.
小智 7
“包括规则。您可以包括其他验证器的规则,前提是它们验证相同的类型。”
public class PersonValidator : AbstractValidator<Person> {
public PersonValidator() {
Include(new PersonAgeValidator());
Include(new PersonNameValidator());
}
}
Run Code Online (Sandbox Code Playgroud)
https://docs.fluidation.net/en/latest/include-rules.html
小智 5
另一种可能性是覆盖验证:
public override ValidationResult Validate(ValidationContext<FooBar> context)
{
var fooResult = new FooValidator().Validate(context.InstanceToValidate);
var barResult = new BarValidator().Validate(context.InstanceToValidate);
var errors = new List<ValidationFailure>();
errors.AddRange(fooResult.Errors);
errors.AddRange(barResult.Errors);
return new ValidationResult(errors);
}
Run Code Online (Sandbox Code Playgroud)