马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
媒介
FluentValidation 是一个流行的 .NET 库,用于构建强范例的验证规则。它通常用于验证领域模型、DTO等对象。
注意:在ASP.NET Core中,我们可以利用FluentValidation.AspNetCore包来更好地集成,它提供了自动验证的功能,这样我们就不需要在每个Action中手动调用验证了。
一、利用步骤
1.安装 NuGet 包
- 实验下令
- Install-Package FluentValidation.AspNetCore
复制代码 2.创建模型
- UserRequest.cs
- namespace HostedService.Entity.ResOrReqEntity
- {
- public class UserRequest
- {
- public long Id { get; set; }
- public string UserName { get; set; }
- public string Email { get; set; }
- public string Password { get; set; }
- public string PasswordAgain { get; set; }
- }
- }
复制代码 3.创建验证器
- UserRequestValidate.cs
- using FluentValidation;
- using HostedService.Entity;
- using HostedService.Entity.ResOrReqEntity;
- using Microsoft.AspNetCore.Http.HttpResults;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.AspNetCore.Mvc;
- namespace HostedService.ValidateService
- {
- public class UserRequestValidate : AbstractValidator<UserRequest>
- {
- private readonly UserManager<User> _user;
- public UserRequestValidate(UserManager<User> user)
- {
- _user= user;
- RuleFor(x => x.Email).NotNull().EmailAddress()
- .WithMessage("邮箱不合法")
- .Must(x => x.EndsWith("@163.com") || x.EndsWith("@qq.com"))
- .WithMessage("邮箱只支持163或QQ邮箱");
- RuleFor(x => x.UserName).NotNull().Length(3, 10)
- .WithMessage("用户名长度需要为3-10个")
- .MustAsync(FindUserByNameAsync)
- //.MustAsync(async (x, _) => await user.FindByNameAsync(x) == null)
- .WithMessage("用户已存在");
- RuleFor(x => x.Password).Equal(x => x.PasswordAgain)
- .WithMessage("两次输入的密码必须一致");
- }
- private async Task<bool> FindUserByNameAsync(string name, CancellationToken token)
- {
- var res=await _user.FindByNameAsync(name);
- return res == null;
- }
- }
- }
复制代码 4.设置 Program.cs
- // 注册验证器(使用异步支持)
- builder.Services.AddValidatorsFromAssemblyContaining<Program>(ServiceLifetime.Scoped);
- // 自定义验证错误响应
- builder.Services.Configure<ApiBehaviorOptions>(options =>
- {
- options.InvalidModelStateResponseFactory = context =>
- {
- var errors = context.ModelState
- .Where(e => e.Value.Errors.Count > 0)
- .ToDictionary(
- kvp => kvp.Key,
- kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
- );
- return new BadRequestObjectResult(new
- {
- Status = 400,
- Message = "Validation failed",
- Errors = errors
- });
- };
- });
复制代码 5.创建控制器
- TestController.cs
- using HostedService.Entity;
- using HostedService.Entity.ResOrReqEntity;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.AspNetCore.Mvc;
- namespace HostedService.Controllers
- {
- [Route("api/[controller]/[action]")]
- [ApiController]
- public class TestController : ControllerBase
- {
- private readonly UserManager<User> _userManager;
- private readonly RoleManager<Role> _roleManager;
- private readonly IWebHostEnvironment _webHostEnvironment;
- public TestController(UserManager<User> userManager, RoleManager<Role> roleManager, IWebHostEnvironment webHostEnvironment)
- {
- _userManager = userManager;
- _roleManager = roleManager;
- _webHostEnvironment = webHostEnvironment;
- }
-
- [HttpPost]
- public async Task<IActionResult> Add(UserRequest userRequest, [FromServices] IValidator<UserRequest> validator)
- {
- //手动出发验证
- var validateRes =await validator.ValidateAsync(userRequest);
- if (!validateRes.IsValid)
- {
- return BadRequest(validateRes.ToDictionary());
- }
- User user = new User { UserName = userRequest.UserName, Email = userRequest.Email };
- await _userManager.CreateAsync(user, userRequest.Password);
- return Ok();
- }
- }
- }
复制代码 6.测试效果
- 示例
UserRequest- {
- "id": 0,
- "userName": "LGF",
- "email": "[email protected]",
- "password": "123ggg",
- "passwordAgain": "123gg"
- }
复制代码 Response Body- Error: response status is 400
- Response body
- {
- "Email": [
- "邮箱只支持163或QQ邮箱"
- ],
- "UserName": [
- "用户已存在"
- ],
- "Password": [
- "两次输入的密码必须一致"
- ]
- }
复制代码 二、常见问题及注意事项
- 验证器未触发
- 确保 AddFluentValidation() 在 AddControllers() 之后调用
- 检查验证器是否在注册的程序集中
- 生命周期管理
- 验证器发起注册为 Scoped 生命周期
- 异步验证中注入的仓储需支持异步操纵
- 混合验证规则优先级
- RuleFor(x => x.UserName).NotNull().Length(3, 10) //同步验证
- .WithMessage("用户名长度需要为3-10个")
- .MustAsync(FindUserByNameAsync)//异步验证
- .WithMessage("用户已存在");
复制代码 三、性能优化发起
- 同步验证优先原则:将轻量级验证(如格式校验)放在同步阶段
- 异步验证批处置惩罚:对需要访问外部资源的验证举行归并查询
- 验证缓存机制:对高频静态数据(如行政区划)可添加内存缓存
总结
通过以上设置,您可以在 ASP.NET Core 8.0 Web API 中实现验证逻辑,保持控制器简洁并返回布局化的错误相应。
|