Fluent Validation - pass parameter to collection validator

六眼飞鱼酱① 提交于 2020-01-24 04:11:20

问题


I'm using fluent validation i ASP.NET MVC application and I've had a problem. This is my rule:

RuleFor(x => x.SimpleList)
       .SetCollectionValidator(new SimpleListValidator())
       .When(x => x.Type == SimpleEnum.SpecificType);

I want to pass x.Type param to SimpleListValidator, how can I do this? Some kind of extension method? It should looks like:

    RuleFor(x => x.SimpleList)
       .SetCollectionValidator(new SimpleListValidator(x => x.Type))
       .When(x => x.Type == SimpleEnum.SpecificType);

回答1:


After you set collection validator for property - you can forget about fact, that main model and (n - 1) submodels exists except submodel being currently validated. And there is no way to pass main model as a parameter in SetCollectionValidator.

So you have to use RuleForEach method instead of setting collection validator:

RuleForEach(x => x.SubEntities)
    .Must((model, submodel) => IsValidFirst(submodel, model)) // your rules should go here to be applicable to each collection item
        .WithMessage("The item with values {0}, {1} has duplicates in collection of {2} items",
            (model, submodel) => submodel.Field1,
            (model, submodel) => submodel.Field2,
            (model, submodel) => model.SubEntities.Count); // for error message building you can access both model and submodel being validated
    .Must((model, submodel) => IsValidSecond(submodel, model)) // yet another rule
        .WithMessage("...")
    .When(model => 
        model.Type == SimpleEnum.SpecificType) // can access to main model only, but it is enough for your purposes

I guess that possibility to tell child validator about fact, that parent model could exists, should be implemented in future, but right now there is the only working approach, mentioned above.

UPDATE

You can create custom ModelBinder, that would set Parent property of each subentity to main entity value, and continue using SetCollectionValidator().




回答2:


It is possible and you can do it like this:

RuleFor(x => x.SimpleList)
   .SetCollectionValidator(model => new SimpleListValidator(model))
   .When(x => x.Type == SimpleEnum.SpecificType);

In your SetCollectionValidator class you have to create a constructor accepting your model as a parameter (or anything else you'd like to pass to the validator). Remember though that you should leave a parameter-less constructor in the SimpleListValidator class.



来源:https://stackoverflow.com/questions/32247571/fluent-validation-pass-parameter-to-collection-validator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!