Asp.Net Core FluentValidation校验框架

[复制链接]
发表于 2025-7-8 14:14:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

媒介

FluentValidation 是一个流行的 .NET 库,用于构建强范例的验证规则。它通常用于验证领域模型、DTO等对象。
注意:在ASP.NET Core中,我们可以利用FluentValidation.AspNetCore包来更好地集成,它提供了自动验证的功能,这样我们就不需要在每个Action中手动调用验证了。
一、利用步骤

1.安装 NuGet 包


  • 实验下令
    1. Install-Package FluentValidation.AspNetCore
    复制代码
2.创建模型


  • UserRequest.cs
    1. namespace HostedService.Entity.ResOrReqEntity
    2. {
    3.     public class UserRequest
    4.     {
    5.         public long Id { get; set; }
    6.         public string UserName { get; set; }
    7.         public string Email {  get; set; }
    8.         public string Password { get; set; }
    9.         public string PasswordAgain {  get; set; }
    10.     }
    11. }
    复制代码
3.创建验证器


  • UserRequestValidate.cs
    1. using FluentValidation;
    2. using HostedService.Entity;
    3. using HostedService.Entity.ResOrReqEntity;
    4. using Microsoft.AspNetCore.Http.HttpResults;
    5. using Microsoft.AspNetCore.Identity;
    6. using Microsoft.AspNetCore.Mvc;
    7. namespace HostedService.ValidateService
    8. {
    9.     public class UserRequestValidate : AbstractValidator<UserRequest>
    10.     {
    11.         private readonly UserManager<User> _user;
    12.         public UserRequestValidate(UserManager<User> user)
    13.         {
    14.             _user= user;      
    15.             RuleFor(x => x.Email).NotNull().EmailAddress()
    16.                 .WithMessage("邮箱不合法")
    17.                 .Must(x => x.EndsWith("@163.com") || x.EndsWith("@qq.com"))
    18.                 .WithMessage("邮箱只支持163或QQ邮箱");
    19.             RuleFor(x => x.UserName).NotNull().Length(3, 10)
    20.                 .WithMessage("用户名长度需要为3-10个")
    21.                 .MustAsync(FindUserByNameAsync)
    22.                 //.MustAsync(async (x, _) => await user.FindByNameAsync(x) == null)
    23.                 .WithMessage("用户已存在");
    24.             RuleFor(x => x.Password).Equal(x => x.PasswordAgain)
    25.                 .WithMessage("两次输入的密码必须一致");
    26.         }
    27.         private async Task<bool> FindUserByNameAsync(string name, CancellationToken  token)
    28.         {
    29.             var res=await _user.FindByNameAsync(name);
    30.             return res == null;
    31.         }
    32.     }
    33. }
    复制代码
4.设置 Program.cs


  • Program.cs
  1. // 注册验证器(使用异步支持)
  2. builder.Services.AddValidatorsFromAssemblyContaining<Program>(ServiceLifetime.Scoped);
  3. // 自定义验证错误响应
  4. builder.Services.Configure<ApiBehaviorOptions>(options =>
  5. {
  6.     options.InvalidModelStateResponseFactory = context =>
  7.     {
  8.         var errors = context.ModelState
  9.             .Where(e => e.Value.Errors.Count > 0)
  10.             .ToDictionary(
  11.                 kvp => kvp.Key,
  12.                 kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
  13.             );
  14.         return new BadRequestObjectResult(new
  15.         {
  16.             Status = 400,
  17.             Message = "Validation failed",
  18.             Errors = errors
  19.         });
  20.     };
  21. });
复制代码
5.创建控制器


  • TestController.cs
    1. using HostedService.Entity;
    2. using HostedService.Entity.ResOrReqEntity;
    3. using Microsoft.AspNetCore.Http;
    4. using Microsoft.AspNetCore.Identity;
    5. using Microsoft.AspNetCore.Mvc;
    6. namespace HostedService.Controllers
    7. {
    8.     [Route("api/[controller]/[action]")]
    9.     [ApiController]
    10.     public class TestController : ControllerBase
    11.     {
    12.         private readonly UserManager<User> _userManager;
    13.         private readonly RoleManager<Role> _roleManager;
    14.         private readonly IWebHostEnvironment _webHostEnvironment;
    15.         public TestController(UserManager<User> userManager, RoleManager<Role> roleManager, IWebHostEnvironment webHostEnvironment)
    16.         {
    17.             _userManager = userManager;
    18.             _roleManager = roleManager;
    19.             _webHostEnvironment = webHostEnvironment;
    20.         }
    21.         
    22.              [HttpPost]
    23.              public async Task<IActionResult> Add(UserRequest userRequest, [FromServices] IValidator<UserRequest> validator)
    24.              {
    25.                       //手动出发验证
    26.                  var validateRes =await validator.ValidateAsync(userRequest);
    27.                  if (!validateRes.IsValid)
    28.                  {
    29.                      return BadRequest(validateRes.ToDictionary());
    30.                  }
    31.                  User user = new User { UserName = userRequest.UserName, Email = userRequest.Email };
    32.                  await _userManager.CreateAsync(user, userRequest.Password);
    33.                  return Ok();
    34.              }
    35.     }
    36. }
    复制代码
6.测试效果


  • 示例
    UserRequest
    1. {
    2.   "id": 0,
    3.   "userName": "LGF",
    4.   "email": "[email protected]",
    5.   "password": "123ggg",
    6.   "passwordAgain": "123gg"
    7. }
    复制代码
    Response Body
    1. Error: response status is 400
    2. Response body
    3. {
    4.   "Email": [
    5.     "邮箱只支持163或QQ邮箱"
    6.   ],
    7.   "UserName": [
    8.     "用户已存在"
    9.   ],
    10.   "Password": [
    11.     "两次输入的密码必须一致"
    12.   ]
    13. }
    复制代码
二、常见问题及注意事项



  • 验证器未触发

    • 确保 AddFluentValidation() 在 AddControllers() 之后调用
    • 检查验证器是否在注册的程序集中

  • 生命周期管理

    • 验证器发起注册为 Scoped 生命周期
    • 异步验证中注入的仓储需支持异步操纵

  • 混合验证规则优先级
    1. RuleFor(x => x.UserName).NotNull().Length(3, 10) //同步验证
    2. .WithMessage("用户名长度需要为3-10个")
    3. .MustAsync(FindUserByNameAsync)//异步验证
    4. .WithMessage("用户已存在");
    复制代码
三、性能优化发起



  • 同步验证优先原则:将轻量级验证(如格式校验)放在同步阶段
  • 异步验证批处置惩罚:对需要访问外部资源的验证举行归并查询
  • 验证缓存机制:对高频静态数据(如行政区划)可添加内存缓存

总结

通过以上设置,您可以在 ASP.NET Core 8.0 Web API 中实现验证逻辑,保持控制器简洁并返回布局化的错误相应。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表