asp.net-mvcfoolproof-validation

Manually trigger foolproof validation


I'm using Foolproof Validation so I can use [RequiredIf] attributes on my view model. The problem is that I'd like to trigger validation within my code using the same logic outside a controller.

I've tried creating my own validation context and using Validatior.TryValidateObject; however, it fails with Foolproof's custom RequiredIf validator. Is there a way to take my model and validate it other than passing it to a controller?

Am I using the wrong approach?

Here is my code:

var draftModel = _draftHelper.LoadDraft(draftId);

var validationResults = new List<ValidationResult>();

var vc = new ValidationContext(draftModel, null, null);

var isValidDraft = Validator.TryValidateObject(draftModel, vc, 
                                               validationResults, true);

And the error I get is on the TryValidateObject line

System.NotImplementedException: The method or operation is not implemented.


Solution

  • I think a better approach would be to use FluentValidation, not foolproof validation. I personally think Fluent is nicer than attributes too :).

    Using FluentValidation, you are also able to validate your model without the use of a Controller.

    DraftVM draft = draftRepository.Get(draftId);
    
    var DraftValidator validator = new DraftVMValidator();
    ValidationResult results = validator.Validate(draft);
    
    public class DraftVMValidator : AbstractValidator<DraftViewModel>
    {
          public DraftVMValidator()
          {
    
             RuleFor(vm => vm.OptionalField)
                .Must(BeFilledIfNameNotEmpty)
                .WithMessage("Optional Field required because you filled out Name field");
          }
    
    
          public bool BeFilledIfNameNotEmpty(DraftVM viewModel)
          {
                return !string.IsNullOrWhiteSpace(viewModel.Name);
          }
    
    } 
    

    This will NOT give you a System.NotImplemented exception.

    This validator is DRY because you can also plug it into ASP.NET MVC Validation.
    You can simply call the following code in Global.asax or App_Start etc. One validator for all, bind it to MVC Model Validation or use it in any normal application.

    FluentValidationModelValidatorProvider.Configure(); // This will bind it for you
    

    If you use Inversion of Control container like Ninject, FluentValidation also has a plugin to work with that. More available on their documentation in link provided above.

    I have a pretty big project example in my Github if you want to see more examples of this Validator instead of FoolProof. Example Validators with ASP.NET MVC 4