如何使用 FluentValdation 而不是数据注释来验证请求?

How to validate requests with FluentValdation instead of data annotations?

我使用以下设置创建了一个新的 .Net 5 Web API

public class MyController : ControllerBase
{
    [HttpGet("{Title}")]
    public ActionResult<string> Get([FromRoute] RouteModel routeModel)
    {
        return Ok(routeModel);
    }
}

public class RouteModel
{
    [MinLength(3)]
    public string Title { get; set; }
}

请求验证工作正常。因为我使用的是 FluentValidation,所以我安装了包

FluentValidation.AspNetCore v10.3.0

并将 Startup.ConfigureServices 方法更新为

public void ConfigureServices(IServiceCollection services)
{
    services.AddValidatorsFromAssemblies(AppDomain.CurrentDomain.GetAssemblies());
    services.AddControllers();
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication", Version = "v1" });
    });
}

我没有使用数据注释,而是从 RouteModel.Title 中删除了数据注释并创建了这个验证器

public class RouteModelValidator : AbstractValidator<RouteModel>
{
    public RouteModelValidator()
    {
        RuleFor(model => model.Title).MinimumLength(3);
    }
}

我期望 ValidationException 如果标题的长度小于 3,这将导致 500 状态代码。但似乎不再有验证触发器,请求总是通过。

有人知道丢失了什么吗?

  1. 将 FluentValidation 注册为

    services
      .AddFluentValidation(x => x.RegisterValidatorsFromAssemblies(AppDomain.CurrentDomain.GetAssemblies()));
    
  2. ApiController 属性标记您的控制器

    [ApiController]
    public class MyController : ControllerBase
    

否则,您应该手动验证 ModelState,例如:

[HttpGet("{Title}")]
public ActionResult<string> Get([FromRoute] RouteModel routeModel)
{
   if (!ModelState.IsValid)
   {
      return BadRequest("bad");
   }
   return Ok(routeModel);
}

Some info:

It depends on the type of controller - if you're using the [ApiController] attribute, then ASP.NET will generate a Bad Request result automatically. If you don't use the ApiController attribute (ie for non-api controllers, such as where you return a view), then you're expected to handle the ModelState.IsValid check manually (see the asp.net doc link above). But again, this is a convention of ASP.NET, it isn't a feature of FluentValidation.