在ASP.NET Core中是否可以使用自定义的ModelState验证提供程序?

6

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
}

如何将验证器与IOC和自定义ModelState验证提供程序集成,而不是在我的操作中定义它?

1个回答

12
首先,您需要实现自定义的 IModelValidatorProviderIModelValidator
请考虑我编写的这个简单示例:
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>();
    }
}

您需要将自定义提供程序添加到MVC选项中:

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

框架内置示例:

DataAnnotationsModelValidatorProvider.cs
DataAnnotationsModelValidator.cs


为什么要使用ISelfValidatableModel?有一件我觉得奇怪的事情是:如果验证器是异步的,如何在IModelValidator中包含它,因为IModelValidator不支持异步?难道IModelValidator没有ValidateAsync方法不奇怪吗? - Miguel Moura
在这个例子中,拥有ISelfValidatableModel只是为了好玩。目前这个API不是异步的。 - Mike
你知道是否有计划使模型验证异步化吗? - Miguel Moura

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接