1

I am trying to manually validate a model (PageModel) that has a property (Questions) which is an IEnumerable of polymorphic types. I couldn't get this to work automatically so I am attempting to use the code below.

public IActionResult Submit([FromServices] IValidatorFactory factory, [FromForm] PageModel model)
{
    foreach ( var question in model.Questions )
    {
        Type questionType = question.GetType();
        var validator = factory.GetValidator(question.GetType());
        var results = validator.Validate(ValidationContext.CreateWithOptions(question));
        results.AddToModelState(ModelState, null);
    }

However, IValidator.Validate() does not take the model (question) but instead needs a ValidationContext<T> or an IValidationContext, neither of which I can create without knowing the type of validator at compile time.

The example of manual validation in the docs shows a specific validator being created but I would like FluentValidation to find the correct one with the factory and then call it.

Does anyone know how to do this?

Yehor Androsov
  • 4,885
  • 2
  • 23
  • 40
Luke Briner
  • 708
  • 4
  • 21

1 Answers1

3

So I worked out how to do this by the fact that the type needed for ValidationContext is not important to work, so I just use an object. I also need to use the correct prefix (in my case) when adding the errors to the model state so that they map onto the correct model properties (which is why I am using a for loop instead of foreach).

for ( var i = 0; i < model.Questions.Count(); ++i )
{
    var question = model.Questions[i];
    Type questionType = question.GetType();
    var validator = factory.GetValidator(questionType);
    var results = validator.Validate(new ValidationContext<object>(question));
    results.AddToModelState(ModelState, $"Questions[{i}]");
}
Luke Briner
  • 708
  • 4
  • 21