FluentValidation: Validation not working for nested list of models
Which version of FluentValidation are you using? 6.1.0.1
Which version of ASP.NET are you using? .NET Framework 4.6.1
Describe the issue that you’re having Issue The list of objects inside the model are not getting validated.
Sample classes
public class User {
public int Id { get; set; }
public string Name { get; set; }
public List<Role> Roles { get; set; }
}
public class Role {
public string Name { get; set; }
public string Type { get; set; }
}
public class RoleTypeInteger : Role {
public int Value { get; set; }
}
public class RoleTypeString : Role {
public string Value { get; set; }
}
Validator classes
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.Name).NotNull();
}
}
public class RoleTypeIntegerValidator: AbstractValidator<RoleTypeInteger>
{
public RoleTypeIntegerValidator()
{
RuleFor(x => x.Value).InclusiveBetween(10, 30);
}
}
public class RoleTypeStringValidator: AbstractValidator<RoleTypeString>
{
public RoleTypeStringValidator()
{
RuleFor(x => x.Value).Length(128);
}
}
MVC Controller
public ActionResult MyMethod([ModelBinder(typeof(UserModelBinder))] User viewModel) {...}
Now in my model binder, I convert the received roles to their specific models based on the type property.
Issue The model state is valid even when the validation error should be present.
Ruled out issues Earlier I assumed that there might have been an issue with model binder or polymorphic models, but I tried updating the User model with the following code, where I was only trying to test one type of model, but it still doesn’t work.
public class User {
public int Id { get; set; }
public string Name { get; set; }
public List<RoleTypeInteger> Roles { get; set; }
}
Please suggest what am I missing here.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 17 (10 by maintainers)
If you go with the third option, then your custom validator factory can be based off default implementation (you’d need to add methods for removing items from the ConcurrentDictionary).
You would then wire it up in your application startup routine, at the point you call
FluentValidationModelValidatorProvider.Configure()
, eg:However, personally I would suggest you go with the second option and keep your logic for loading/caching messages separate to FluentValidation’s validator lifetimes.
That’s a limitation of 6.x (RuleFor could only be used for simple properties, not method calls) Modern versions don’t have this limitation, but you will still bypass the expression cache.
The second solution in that link (as well as the second issue I linked to) are more likely to work on 6.x. But I’d still suggest you upgrade to 8.6 if you can.
Hello,
You’re using a very old and unsupported version of FluentValidation, so I can’t really provide much help with this I’m afraid. However, I suspect the issue is likely to be the model binder - if I remember correctly old versions of ASP.NET MVC do not perform validation when using a custom model binder - it bypasses the process. MVC’s recursive validation of properties only kicks in when using the default model binding process. In this case as you’re handling the binding process manually, validation will never occur.
You can confirm this by overriding the validator’s
Validate
method (the overload that accepts a ValidationContext) and placing a breakpoint in this method. If this method is not invoked, then MVC is not running validation, in which case you will need to instantiate and execute the validator manually.Beyond this I’m not able to provide any further help I’m afraid - I don’t have the capacity to provide help for unsupported old versions of the library. If you are able to upgrade to the latest release and still run into problems (8.6.x), then I’d be happy to help further.