asp.net-mvc - FluentValidation 集合属性未验证

标签 asp.net-mvc 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 是因为不同的验证模式取决于工作流中的文档状态)

我正在从 Controller 手动执行验证(没有 MVC 集成)

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


    // ...
}

通过此实现,主类的属性得到了很好的验证,但我还需要验证集合中“Medicamento”类的每个属性。

我可以在这里遗漏什么吗?。是否应使用可用的 RuleForEach 子句对其进行验证?

我们将不胜感激。

最佳答案

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

更新:我找到了 Jeremy Skinner 对这种行为的引用: http://fluentvalidation.codeplex.com/discussions/266920

Rulesets cascade to any child validators, so whichever ruleset is selected for use by the top-level validator will also be used by the child validator. So if you ran the "Minimal" ruleset on the CreateProfileModelValidator, then only rules in the "Minimal" ruleset will be run on both the CreateProfileModelValidator and the ProfileValidator.

关于asp.net-mvc - FluentValidation 集合属性未验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29379259/

相关文章:

asp.net-mvc - Url.Action(action,controller,routeValues) 将 URL 中的 ID 加倍

c# - 如何在 asp.net MVC 的 HTML 帮助程序中将 Razor 与字符串文字混合

asp.net-mvc - 使用 FluentValidation 时将 DataAnnotation 添加到类

c# - SimpleInjector 和 FluentValidationFactory

asp.net-mvc - Fluent 验证 When 子句

c# - FluentValidation:使用 ValidationContext 进行验证

c# - "DataReader already open"有问题

asp.net-mvc - RadioButton用于不在编辑器模板中选择值

c# - 如何全局访问当前的HttpRequestMessage对象?

asp.net-core - 检测到 Microsoft.CodeAnalysis.Common 的版本冲突。直接从项目中引用包来解决此问题