Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use a custom ModelState validation provider in ASP.NET Core?

I have the following ASP.NET CORE action:

public async Task<IActionResult> Post([FromBody]Model model) { 

   IValidator<Model> validator = new Validator<Model>();

   Boolean valid = await validator.ValidateAsync(model); 

   if (!valid)
      return HttpBadRequest(validator.GetErrors());

   // Do something
}

Instead of defining the validator in my action how can I integrate it with IOC and a custom ModelState validation provider?

like image 432
Miguel Moura Avatar asked May 02 '16 12:05

Miguel Moura


Video Answer


1 Answers

First of all you need to implement your custom IModelValidatorProvider and IModelValidator.

Please consider this simple example that I wrote:

public class MyCustomModelValidatorProvider : IModelValidatorProvider
{
    public void CreateValidators(ModelValidatorProviderContext context)
    {
        if (context.ModelMetadata.MetadataKind == ModelMetadataKind.Type)
        {
            var validatorType = typeof(MyCustomModelValidator<>)
                .MakeGenericType(context.ModelMetadata.ModelType);
            var validator = (IModelValidator)Activator.CreateInstance(validatorType);

            context.Results.Add(new ValidatorItem
                                {
                                    Validator = validator,
                                    IsReusable = true
                                });
        }
    }
}

public interface ISelfValidatableModel
{
    string Validate();
}

public class MyCustomModelValidator<T> : IModelValidator where T : ISelfValidatableModel
{
    public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context)
    {
        var model = (T)context.Model;

        var error = model.Validate();

        if (!string.IsNullOrEmpty(error))
        {
            return new List<ModelValidationResult>
            {
                new ModelValidationResult(model.ToString(), error)
            };
        }

        return Enumerable.Empty<ModelValidationResult>();
    }
}

You need to add your custom provider into MVC options:

services.AddMvc(options =>
{
    options.ModelValidatorProviders.Add(new MyCustomModelValidatorProvider());
});

Framework built-in examples:

DataAnnotationsModelValidatorProvider.cs
DataAnnotationsModelValidator.cs

like image 159
Mike Avatar answered Oct 05 '22 12:10

Mike