使用 WebApi [Route] 属性时 FluentValidation 不起作用

Posted

技术标签:

【中文标题】使用 WebApi [Route] 属性时 FluentValidation 不起作用【英文标题】:FluentValidation Doesn't Work When Using WebApi [Route] Attribute 【发布时间】:2016-08-23 18:53:39 【问题描述】:

我在只有一个 HttpGet 方法的 WebApi 项目控制器中成功实现了 FluentValidation。当我添加另一个 HttpGet 方法时,我为这两个方法添加了路由属性。即 [Route("Method1")] 和 [Route("Method2")]。

现在无论我是否输入任何数据,ModelState 都会返回为真。

这是我的代码。

WebApiConfig

public static class WebApiConfig

    public static void Register(HttpConfiguration config)
    

        config.Filters.Add(new ValidateModelStateFilter());

        //FluentValidation
        FluentValidationModelValidatorProvider.Configure(config);

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "action/id",
            defaults: new  controller = "Menu", id = RouteParameter.Optional
        );


    

ValidateModelStateFilter

public class ValidateModelStateFilter : ActionFilterAttribute

    public override void OnActionExecuting(HttpActionContext actionContext)
    
        if (!actionContext.ModelState.IsValid)
        
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
        
    

控制器

[HttpGet]
[Route("Method1")]
public IHttpActionResult ReadAllMenusByApplication([FromUri] ReadAllMenusByApplicationInput input)

        var result = new List<ApplicationMenu>();
        ...

输入对象

using FluentValidation;
using FluentValidation.Attributes;

namespace MenuService.Models

[Validator(typeof(ReadAllMenusByApplicationInputValidator))]
public class ReadAllMenusByApplicationInput

    public ReadAllMenusByApplicationInput() 
        this.ApplicationName = string.Empty;
    

    /// <summary>
    /// The MenuSystem name of the application
    /// </summary>
    public string ApplicationName  get; set; 


public class ReadAllMenusByApplicationInputValidator : AbstractValidator<ReadAllMenusByApplicationInput>

    public ReadAllMenusByApplicationInputValidator()
    
        RuleFor(x => x.ApplicationName).NotEmpty();
    

【问题讨论】:

向控制器显示两个路由以及正在发送的请求示例。 【参考方案1】:

使用本文作为参考

Custom Validation in ASP.NET Web API with FluentValidation

您似乎已经完成了参考文章中的大部分内容。

检查您的配置顺序。

public static class WebApiConfig 
    public static void Register(HttpConfiguration config) 
        // Web API configuration and services
        config.Filters.Add(new ValidateModelStateFilter());

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "action/id",
            defaults: new  controller = "Menu", id = RouteParameter.Optional
        );

        //FluentValidation
        FluentValidationModelValidatorProvider.Configure(config);    
    

FluentValidation 自动将其错误插入ModelState。您应该包含一条错误消息。

public class ReadAllMenusByApplicationInputValidator : AbstractValidator<ReadAllMenusByApplicationInput> 
    public ReadAllMenusByApplicationInputValidator() 
        RuleFor(x => x.ApplicationName).NotEmpty()
            .WithMessage("The Application Name cannot be blank.");
    

该文章的某些内容超出了您的问题范围。主要是包装响应,但其他一切都应该适合你。

【讨论】:

以上是关于使用 WebApi [Route] 属性时 FluentValidation 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS之Route

Web API和属性路由

WebApi 找到了与该请求匹配的多个操作

将 [Authorize] 属性隐式应用于所有 Web API 控制器

使用令牌 WebAPI 对 MVC 应用程序进行身份验证

使用$ http.post时HTTP 405无效方法(HTTP动词)