C# Web Api - IValidatableObject validationContext service provider is null

1.9k Views Asked by At

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?

1

There are 1 best solutions below

1
Samuel Poirier On

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)
            );
    }