此问题是此帖子的后续操作-How to perform async ModelState validation with FluentValidation in Web API?。
我想知道FluentValidation是否可以在.net核心Web API中执行异步ModelState验证。我有一个FluentValidation Validator类,其中包含异步验证方法,例如“ MustAsync”,这意味着在我的业务服务类中,我使用“ ValidateAsync”手动调用了验证器。我也想使用相同的验证器类来验证来自请求的模型。我仔细阅读了文档,了解到唯一的方法是手动调用“ ValidateAsync()”方法,因为.net管道是同步的。我宁愿不必从控制器内部手动调用此方法,我宁愿在启动时注册它(让框架自动在模型上调用验证器),也可以用验证器修饰请求模型。
有人能做到吗?
谢谢!
答案 0 :(得分:0)
基于链接的问题,我对代码进行了一些改动,以使其与ASP.NET Core(以我的情况为2.2)兼容。通常,这是使用IAsyncActionFilter
接口。您可以in the official docs来了解它。
public class ModelValidationActionFilter : IAsyncActionFilter
{
private readonly IValidatorFactory _validatorFactory;
public ModelValidationActionFilter(IValidatorFactory validatorFactory) => _validatorFactory = validatorFactory;
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var allErrors = new Dictionary<string, object>();
// Short-circuit if there's nothing to validate
if (context.ActionArguments.Count == 0)
{
await next();
return;
}
foreach (var (key, value) in context.ActionArguments)
{
// skip null values
if (value == null)
continue;
var validator = _validatorFactory.GetValidator(value.GetType());
// skip objects with no validators
if (validator == null)
continue;
// validate
var result = await validator.ValidateAsync(value);
// if it's valid, continue
if (result.IsValid) continue;
// if there are errors, copy to the response dictonary
var dict = new Dictionary<string, string>();
foreach (var e in result.Errors)
dict[e.PropertyName] = e.ErrorMessage;
allErrors.Add(key, dict);
}
if (allErrors.Any())
{
// Do anything you want here, if the validation failed.
// For example, you can set context.Result to a new BadRequestResult()
// or implement the Post-Request-Get pattern.
}
else
await next();
}
}
如果要全局应用此过滤器,可以将过滤器添加到AddMvc
类中的Startup
调用中。例如:
services.AddMvc(options =>
{
options.Filters.Add<ModelValidationActionFilter>();
// uncomment the following line, if you want to disable the regular validation
// options.ModelValidatorProviders.Clear();
});
答案 1 :(得分:0)
根据@nachtjasmin 上面的回答,您可以通过两种方式添加,
使用 AddMvc
services.AddControllersWithViews(options =>
{
options.Filters.Add<FluentValidationActionFilter>();
});
使用 AddControllersWithViews
services.AddControllersWithViews(options =>
{
options.Filters.Add<FluentValidationActionFilter>();
});
如果您的只是一个 Web API 并且您没有涉及任何 Razor 页面,那么您可以考虑使用 AddControllersWithViews
而不是 AddMvc
,因为 AddMvc
使用 {{1 }} 在内部添加 AddControllersWithViews
。
您可以看到此信息 here for AddMvc 和 here for AddControllersWithViews