Fluent验证规则、子集和嵌套
本文关键字:嵌套 子集 验证 规则 Fluent | 更新日期: 2023-09-27 18:27:16
给定一个类似的验证器类
public class SomeValidator : AbstractValidator<SomeObject>
{
public SomeValidator(){
RuleSet("First",
() => {
RuleFor(so => so.SomeMember).SetValidator(new SomeMemberValidator())
});
RuleSet("Second",
() => ... Code Does Not Matter ... );
RuleSet("Third",
() => ... Code Does Not Matter ... );
}
}
和另一个做内部成员验证
public class SomeMemberValidator: AbstractValidator<SomeMember>
{
public SomeValidator(){
RuleSet("Fourth",
() => {
... Code Does Not Matter ...
});
}
}
问题是,我想运行特定的规则集:"第一"、"第二"answers"第四"。我不想让"第三"跑。
鉴于Validate方法签名只接受一个规则集参数,我看不出有任何方法可以做到这一点。有"*",但我不想执行所有规则。
请帮忙。
您可以使用验证器构造函数而不是RuleSet来解决此问题。只需在验证器类内部创建枚举,然后在创建验证器时使用其值。
通过这种方式,正确的规则将被激活,这取决于构造函数中设置的模式。
public class UserValidator : AbstractValidator<User>
{
public enum Mode
{
Create,
Edit
}
public UserValidator()
{
// Default rules...
}
public UserValidator(UserValidator.Mode mode)
: this()
{
if (mode == Mode.Edit)
{
// Rules for Edit...
RuleFor(so => so.SomeMember)
.SetValidator(
new SomeMemberValidator(SomeMemberValidator.Mode.SomeMode))
}
if (mode == Mode.Create)
{
// Rules for Create...
RuleFor(so => so.SomeMember)
.SetValidator(
new SomeMemberValidator())
}
}
}
我认为它实际上比使用RuleSet更灵活。
关于FluentValidation MVC集成,只有一个小问题:User
类不能具有属性[Validator(typeof(UserValidator))]
,因为在控制器方法中执行任何操作之前,将使用默认构造函数创建UserValidator。
必须手动创建和调用验证器。例如:
public class UserController : Controller
{
[HttpPost]
public ActionResult Create(User userData)
{
var validator = new UserValidator(UserValidator.Mode.Create);
if (ValidateWrapper(validator, userData, this.ModelState))
{
// Put userData in database...
}
else
{
// ValidateWrapper added errors from UserValidator to ModelState.
return View();
}
}
private static bool ValidateWrapper<T>(FluentValidation.AbstractValidator<T> validator, T data, ModelStateDictionary modelState)
{
var validationResult = validator.Validate(data);
if (!validationResult.IsValid)
{
foreach (var error in validationResult.Errors)
modelState.AddModelError(error.PropertyName, error.ErrorMessage);
return false;
}
return true;
}
}
您可以执行多个RuleSet,但我认为您不能执行内部RuleSet。
validator.Validate(new ValidationContext<SomeObject>(person, new PropertyChain(), new RulesetValidatorSelector("First", "Second", "Fourth")));
源
另一种选择是研究源代码并尝试想出一种方法。ValidationContext的第三个参数是接口IValidatorSelector
,也许你可以幸运地使用自定义类。