【问题标题】:How to perform async ModelState validation with FluentValidation in Web API?如何在 Web API 中使用 FluentValidation 执行异步 ModelState 验证?
【发布时间】:2016-01-21 14:28:37
【问题描述】:

我设置了一个 Web api 项目以使用 FluentValidation,并使用 webapi integration package 进行 FluentValidation。然后我创建了一个使用CustomAsync(...) 对数据库运行查询的验证器。

问题是在等待数据库任务时验证似乎死锁了。我做了一些调查,似乎MVC ModelState API是同步的,它调用同步的Validate(...)方法使FluentValidation调用task.Result,导致死锁。

假设异步调用不适用于 webapi 集成验证是否正确?

如果是这样的话,还有什么选择? WebApi ActionFilters 似乎支持异步处理。我是否需要构建自己的过滤器来手动处理验证,还是已经有一些我没有看到的东西可以做?

【问题讨论】:

    标签: c# asp.net-web-api async-await fluentvalidation model-validation


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-26
      • 1970-01-01
      • 2018-02-25
      • 2022-11-09
      • 1970-01-01
      • 2019-02-09
      相关资源
      最近更新 更多