流畅的验证不适用于列表对象

Raj*_*Gan 2 c# asp.net fluentvalidation asp.net-web-api

我正在尝试验证 webApi 2 中的输入对象列表。

但它没有验证。Modelstate 始终设置为 true。

示例代码:

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
} 

public class ClassAValidator : AbstractValidator<A>
{
    public classAValidator()
    {
        RuleSet("ClassA",()=>{
            RuleFor(x => x.Id).NotEmpty().WithMessage("The Idcan't be Empty or Zero");
            RuleFor(x => x.Name).NotEmpty().Length(10).WithMessage("Name Should be Six Char length");
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:字符串字段必须是 6 个字符。

应用程序编程接口:

 [HttpPut]
 public async Task<IHttpActionResult> Put([FromBody] List<A> alist)
 {
     if(!ModelState.IsValid) throw new InvalidDataException(ModelState,"Data Validation Failed for Upload Class A"); 
     // Model State is Always true
 }
Run Code Online (Sandbox Code Playgroud)

谁能指出我错过了什么?

更新:我尝试了如我应该在 FluentValidation 中为集合创建新类型吗?

但仍然有同样的问题。

已解决更新:

问题是规则集的使用导致验证未触发。在删除“RuleSet”时,即使没有 List[A] Validator 类的定义,它也可以工作。

来自 Jeremy Skinner 的消息:第一个问题是您的规则包含在规则集中,因此它们永远不会被执行。规则集是选择加入的,自动集成仅调用不在规则集中的规则。

Rik*_*Rik 7

首先,ModelState.IsValidASP.NET MVC 构造验证(默认情况下)模型绑定是否正确完成。除非您在 MVC 配置中设置它,否则它与 FluentValidation 无关。

您需要确保验证器被调用。要验证 List ofA及其元素,您需要两个验证器:一个用于 type A,另一个用于 List/Collection/IEnumerable of A

public class ClassAValidator : AbstractValidator<A>
{
    public ClassAValidator()
    {
        RuleFor(x => x.Id).NotEmpty().WithMessage("Id can't be empty");
        RuleFor(x => x.Name).NotEmpty().Length(10).WithMessage("Name should have length 10");
    }
}

public class ClassACollectionValidator : AbstractValidator<IEnumerable<A>>
{
    public ClassACollectionValidator ()
    {
        RuleFor(x =>x).SetCollectionValidator(new ClassAValidator());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以按如下方式验证您的列表

 [HttpPut]
 public async Task<IHttpActionResult> Put([FromBody] List<A> alist)
 {
     if(!ModelState.IsValid) throw new InvalidDataException(ModelState,"Data Validation Failed for Upload Class A"); 

     var validator = new ClassACollectionValidator();
     var result = validator.Validate(alist);
 }
Run Code Online (Sandbox Code Playgroud)

或者,您可以按如下方式组合两个验证器:

public class ClassACollectionValidator : AbstractValidator<IEnumerable<A>>
{
    public ClassACollectionValidator ()
    {
        RuleForEach(x => x.Id).NotEmpty().WithMessage("Id can't be empty");
        RuleForEach(x => x.Name).NotEmpty().Length(10).WithMessage("Name should have length 10");
    }
}
Run Code Online (Sandbox Code Playgroud)