Selective validation of child properties - Fluent Validation in MVC

后端 未结 3 1868
天命终不由人
天命终不由人 2021-02-10 14:00

I\'m using Fluent Validation with the Ninject.Web.Mvc.FluentValidation library to automatically wire up all of my validators (and use dependency injection to create the validato

相关标签:
3条回答
  • 2021-02-10 14:15

    Since the auto-wireup wouldn't have a way to conditionally understand when to apply the ChildValidator class during model binding, it seems like you have a few alternatives:

    1. Decide if reuse of the child view models is that important. Faced with this situation, I would probably collapse the children into the parent for this view if the Child objects weren't very complex and there weren't more than a couple of views that used Child objects separately. I'm always a bit more reluctant to be super-DRY with view models, since page structures tend to diverge over time in my experience.
    2. Clear ModelState errors for Child2. From here, you could take complete control of validation for Child2, including a separate validator for Child2 altogether in this unique context and applying it manually. Which is one of the reasons I love FluentValidation - the ability to apply different validation logic to the same view model in different contexts, unlike data annotations.

    The value of auto-wireup (i.e., all the extra code it precludes) would rule out the option of turning that off for this one case, IMO.

    0 讨论(0)
  • 2021-02-10 14:26

    You forget to set validator to second child property:

    public class ParentValidator : AbstractValidator<Parent>
    {
        public ParentValidator()
        {
             RuleFor(model => model.Name).NotEmpty();
             RuleFor(model => model.Child1).SetValidator(new ChildValidator());
             RuleFor(model => model.Child2).SetValidator(new ChildValidator());
        }
    }
    
    0 讨论(0)
  • 2021-02-10 14:26

    If you don't want to auto wireup child validators you can add empty interface to child validator:

    public class PersonalDataValidator : AbstractValidator, IChildValidator

    And then in your factory:

    public class FluentValidatorFactory : ValidatorFactoryBase
    {
        private readonly IKernel _kernel;
    
        public FluentValidatorFactory(IKernel kernel)
        {
            _kernel = kernel;
        }
    
        public override IValidator CreateInstance(Type validatorType)
        {
            IValidator validator = _kernel.Resolve(validatorType) as IValidator;
    
            ////we dont want that windosr auto wires up all child validators. 
            var childValidator = validator as IChildValidator;
    
            if (childValidator == null)
            {
                return validator;
            }
    
                return null;
        }
    }
    
    0 讨论(0)
提交回复
热议问题