如何在Web API中使用FluentValidation执行异步ModelState验证? [英] How to perform async ModelState validation with FluentValidation in Web API?

查看:184
本文介绍了如何在Web API中使用FluentValidation执行异步ModelState验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设置了一个Web api项目以使用 webapi集成软件包使用FluentValidation. FluentValidation.然后,我创建了一个验证器,该验证器使用CustomAsync(...)对数据库运行查询.

I setup a web api project to use FluentValidation using the webapi integration package for FluentValidation. Then I created a validator that uses CustomAsync(...) to run queries against the database.

问题在于,等待数据库任务时验证似乎陷入僵局.我进行了一些调查,看来MVC ModelState API是同步的,并且它调用了同步的Validate(...)方法,该方法使FluentValidation调用task.Result,从而导致死锁.

The issue is that the validation seems to deadlock when awaiting for the database task. I did some investigation, it seems that the MVC ModelState API is synchronous, and it calls a synchronous Validate(...) method that makes FluentValidation to call task.Result, causing the deadlock.

假设异步调用无法与webapi集成验证一起使用是否正确?

Is it correct to assume that async calls won't work well with webapi integrated validation?

如果是这种情况,还有什么选择? WebApi ActionFilters似乎支持异步处理.我是否需要构建自己的过滤器来手动处理验证,还是已经存在一些我没有看到的事情?

And if that is the case, what is the alternative? WebApi ActionFilters seem to support for async processing. Do I need to build my own filter to handle the validation manually or is there something already there to do that that I'm not seeing?

推荐答案

我最终创建了一个自定义过滤器,并完全跳过了内置验证:

I ended up creating a custom filter and skipped built-in validation entirely:

public class WebApiValidationAttribute : ActionFilterAttribute
{
    public WebApiValidationAttribute(IValidatorFactory factory)
    {
        _factory = factory;
    }

    IValidatorFactory _factory;

    public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        if (actionContext.ActionArguments.Count > 0)
        {
            var allErrors = new Dictionary<string, object>();

            foreach (var arg in actionContext.ActionArguments)
            {
                // skip null values
                if (arg.Value == null)
                    continue;

                var validator = _factory.GetValidator(arg.Value.GetType());

                // skip objects with no validators
                if (validator == null)
                    continue;

                // validate
                var result = await validator.ValidateAsync(arg.Value);

                // if there are errors, copy to the response dictonary
                if (!result.IsValid)
                {
                    var dict = new Dictionary<string, string>();

                    foreach (var e in result.Errors)
                        dict[e.PropertyName] = e.ErrorMessage;

                    allErrors.Add(arg.Key, dict);
                }
            }

            // if any errors were found, set the response
            if (allErrors.Count > 0)
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, allErrors);
                actionContext.Response.ReasonPhrase = "Validation Error";
            }
        }
    }
}

这篇关于如何在Web API中使用FluentValidation执行异步ModelState验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆