这是我第一次尝试实现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子句验证?
任何帮助将不胜感激。
答案 0 :(得分:1)
似乎RuleSet设置正在应用于子验证器以及主验证器。
我在xUnit.net测试中测试了你的代码,并确认了它。
如果您更改规则集以执行,您应该会发现它按预期工作:
CasoValidator validator = new CasoValidator();
FluentValidation.Results.ValidationResult validate = validator.Validate(c, ruleSet: "default,Iniciar");
&#39;默认&#39;规则集将适用于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);
}
更新:我发现Jeremy Skinner对此行为的引用: http://fluentvalidation.codeplex.com/discussions/266920
规则集级联到任何子验证器,因此无论哪个规则集都是 选择供顶级验证器使用的也将被使用 儿童验证员。 所以,如果你运行&#34; Minimal&#34; CreateProfileModelValidator上的规则集,然后只有&#34; Minimal&#34;中的规则。规则集 将在上运行 CreateProfileModelValidator和 ProfileValidator。
答案 1 :(得分:0)
作为补充: 名为GroupMemberIds的集合应具有AdminMemebrId:
RuleFor(r => new { r.GroupMemberIds, r.AdminMemberId }).Must(a => a.GroupMemberIds.Contains(a.AdminMemberId));