5

I am trying to use IValidatableObject validation in a web api 2 context. The Validate method is getting called, but the ValidationContext parameter passed has a method called GetService which always returns null because the service provider of the validation context is never set.

From all my research, we can easily configure this in the MVC framework, but I didn't find anything on how to configure it in web api 2.

How do we set the service provider to the validation context when validating models passed to an ApiController?

Samuel Poirier
  • 1,240
  • 2
  • 15
  • 30
  • Could you please provide a link how you "easily configure this in the MVC framework". After all research I have done, it seems like MVC framework isn't using the ValidationContext.ServiceProvider at all. – L_M Mar 23 '16 at 06:21

1 Answers1

5

Ok, I found the solution.

The problem I had was that I was trying to completely replace the DataAnnotationsModelValidatorProvider, but the framework doesn't support that. In the end, I had to look for the current one in place and then register my custom factories which will setup the validation context that will be used in the IValidatableObject.

One important note to keep in mind, there are multiple namespaces with the DataAnnotationsModelValidatorProvider, but the one I need is System.Web.Http.Validation.Providers.DataAnnotationsModelValidatorProvider

Here what it looks like:

private static void SetupIoCInValidationContext(
        IServiceProvider serviceProvider)
    {
        IEnumerable<ModelValidatorProvider> modelValidatorProviders =
            GlobalConfiguration
            .Configuration.Services.GetModelValidatorProviders();

        DataAnnotationsModelValidatorProvider provider =
            (DataAnnotationsModelValidatorProvider)
                modelValidatorProviders.Single(
                    x =>
                        x.GetType()
                            .IsTypeOf(
                                typeof(DataAnnotationsModelValidatorProvider)));

        provider.RegisterDefaultAdapterFactory((providers, attribute) =>
            new CustomDataAnnotationsModelValidator(providers, attribute,
                serviceProvider));

        provider.RegisterDefaultValidatableObjectAdapterFactory(
            providers => new CustomValidatableObjectAdapter(providers, serviceProvider)
            );
    }
Samuel Poirier
  • 1,240
  • 2
  • 15
  • 30
  • What do your implementations of CustomDataAnnotationsModelValidator and CustomValidatableObjectAdapter look like? – Rahul Patel Oct 16 '19 at 19:15