2015-03-31 90 views
3

这是我第一次尝试实现FluentValidation,因为我需要覆盖复杂的验证场景。未经验证的FluentValidation集合属性

我试图验证的类有大量的属性,复杂的对象和几个集合。

我没有麻烦来验证主类的属性,甚至检查集合是否为空,但是在验证每个集合中的对象属性时遇到问题。

要实现这一点,我跟着这里记录的例子(下检查“集合校验重新使用”): http://fluentvalidation.codeplex.com/wikipage?title=creatingavalidator

这些是我的模型类(减少以提高可读性)

public class Caso 
{ 
public int Id { get; set; } 
public string Descripcion { get; set; } 
public List<Medicamento> Medicamentos { get; set; } 
} 

public class Medicamento 
{ 
public int Id { get; set; } 
public string Nombre { get; set; } 
} 

这些是验证程序类:

public class CasoValidator : AbstractValidator<CasoAdverso> 
{ 
    public CasoValidator() 
    { 
     RuleSet("Iniciar",() => 
     { 
      // Validated OK 
      RuleFor(x => x.Descripcion).NotEmpty(); 
      // Validated OK 
      RuleFor(x => x.Medicamentos).Must(x => x != null && x.Count > 0).WithMessage("No puede iniciar un caso sin medicamentos cargados"); 
      RuleFor(x => x.Medicamentos).SetCollectionValidator(new MedicamentoValidator()); 
     }); 
    } 
} 

public class MedicamentoValidator : AbstractValidator<Medicamento> 
{ 
    public MedicamentoValidator() 
    { 
     // NOT Validated. Even if the object property is empty the error message doesn't appear. I also checked using "NotNull" and "NotEmpty" clauses 
     RuleFor(x => x.Nombre).NotNull().WithMessage("Debe especificar un nombre"); 
    } 
} 

(注意:我使用RuleSet是因为不同的验证策略作为依赖于工作流中的文档状态)

我从控制器手动执行验证(无MVC集成)

[HttpPost] 
public ActionResult Iniciar(Caso c) 
{ 
    CasoValidator validator = new CasoValidator(); 
    FluentValidation.Results.ValidationResult validate = validator.Validate(c, ruleSet: "Iniciar"); 


    // ... 
} 

随着主类的这种实现性能进行验证罚款我还需要验证集合中“Medicamento”类的每个属性。

我能在这里错过什么吗?是否应该使用RuleForEach子句进行验证?

任何帮助将不胜感激。

回答

1

看来RuleSet设置应用于子验证器以及主验证器。

我在xUnit.net测试中测试了您的代码并进行了确认。

如果你改变你的规则集来执行,你应该找到它按预期工作:

CasoValidator validator = new CasoValidator(); 
FluentValidation.Results.ValidationResult validate = validator.Validate(c, ruleSet: "default,Iniciar"); 

“默认”规则集将在MedicamentoValidator规则的工作。

我没有在文档中找到这个,只能通过测试。

这是样板单元测试:

[Fact] 
public void Test1() 
{ 

    Caso c = new Caso() 
    { 
     Id = 1, 
     Descripcion = "none", 
     Medicamentos = new List<Medicamento>() 
    }; 

    c.Medicamentos.Add(new Medicamento() 
    { 
     Id = 0, 
     Nombre= null 
    }); 

    CasoValidator validator = new CasoValidator(); 
    FluentValidation.Results.ValidationResult validate = validator.Validate(c, ruleSet: "default,Iniciar"); 

    Assert.NotEmpty(validate.Errors); 
} 

更新:我发现杰里米·斯金纳参考正是这种行为: http://fluentvalidation.codeplex.com/discussions/266920

规则集级联以任何子验证,故取其规则集是 被选中供顶级验证器使用,也会被 子验证器使用。因此,如果您在CreateProfileModelValidator上运行“最小”规则集,则只有“最小”规则集 中的规则将在上运行,两者均为 CreateProfileModelValidator和 ProfileValidator。

+0

非常感谢您的快速回复。我已经完成了你的建议调整,现在工作正常。 – Javier 2015-04-01 00:47:18