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

时间:2017-05-02 15:38:05

标签: c# asp.net asp.net-web-api fluentvalidation

我正在尝试在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");
        });
    }
}

注意:字符串字段我们需要精确6个字符。

Api:

 [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
 }

有人能说出我错过的内容吗?

更新: 我尝试了如Should i create a new Type for Collection in FluentValidation?

所示

但仍有同样的问题。

解决了更新:

问题是使用Ruleset导致验证未被触发。在删除&#34; RuleSet&#34;即使没有List [A] Validator类的定义,它也能工作。

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

3 个答案:

答案 0 :(得分:2)

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

您需要确保调用Validators。要验证A及其元素的列表,您需要两个验证器:一个用于类型A,另一个用于列表/集合/ IEnumerable 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());
    }
}

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

 [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);
 }

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

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");
    }
}

答案 1 :(得分:0)

问题是使用Ruleset导致验证未被触发。在删除&#34; RuleSet&#34;即使没有List [A] Validator类的定义,它也能工作。

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

答案 2 :(得分:-1)

看起来你需要在构造函数中包含RuleSet,至少根据这个例子。

https://www.exceptionnotfound.net/custom-validation-in-asp-net-web-api-with-fluentvalidation/

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

}