FastEndpoints启用数据注解验证及统一错误响应格式求助
解决方案
1. 启用数据注解验证替代Fluent Validation
FastEndpoints默认使用Fluent Validation,要切换到数据注解验证,只需在服务配置中替换验证器工厂:
// Program.cs var builder = WebApplication.CreateBuilder(args); builder.Services.AddFastEndpoints(config => { // 替换为数据注解验证器工厂 config.Validation.ValidatorFactoryType = typeof(DataAnnotationsValidatorFactory); }); var app = builder.Build(); app.UseFastEndpoints(); app.Run();
之后在跨项目共享的请求类上直接使用.NET内置的数据注解即可:
// 跨项目共享的请求类 public class CreateUserRequest { [Required(ErrorMessage = "用户名不能为空")] [StringLength(20, ErrorMessage = "用户名长度不能超过20个字符")] public string Username { get; set; } [EmailAddress(ErrorMessage = "邮箱格式不正确")] public string Email { get; set; } [Range(18, 100, ErrorMessage = "年龄必须在18到100之间")] public int Age { get; set; } }
2. 统一返回单一字符串数组的验证错误
要消除嵌套的属性级错误结构,返回扁平的错误消息数组,需要自定义错误响应处理器:
步骤1:实现自定义错误响应处理器
public class FlatErrorResponseProcessor : IErrorResponseProcessor { public ValueTask<object> ProcessAsync(ValidationFailure[] failures, HttpContext ctx, IReadOnlyCollection<ValidationFailure> state, CancellationToken ct) { // 提取所有错误消息,不管是属性级还是通用错误 var errorMessages = failures.Select(f => f.ErrorMessage).ToArray(); return ValueTask.FromResult<object>(new { Errors = errorMessages }); } }
步骤2:注册自定义处理器
在FastEndpoints配置中指定这个处理器:
// Program.cs builder.Services.AddFastEndpoints(config => { config.Validation.ValidatorFactoryType = typeof(DataAnnotationsValidatorFactory); // 注册自定义错误响应处理器 config.Validation.ErrorResponseProcessor = new FlatErrorResponseProcessor(); });
步骤3:手动添加通用错误(可选)
如果需要在业务逻辑中添加非属性级的通用错误,直接在端点中使用AddError方法即可,这些错误会自动加入到扁平数组中:
public class CreateUserEndpoint : Endpoint<CreateUserRequest> { public override void Configure() { Post("/api/users"); AllowAnonymous(); } public override async Task HandleAsync(CreateUserRequest req, CancellationToken ct) { // 模拟业务逻辑校验错误 if (await UserExistsAsync(req.Username)) { AddError("该用户名已被注册"); await SendErrorsAsync(ct); return; } // 正常业务逻辑 await SendOkAsync("用户创建成功", ct); } private Task<bool> UserExistsAsync(string username) { // 模拟数据库查询 return Task.FromResult(username == "admin"); } }
最终响应示例
当存在验证错误时,返回的响应结构如下:
{ "Errors": [ "用户名不能为空", "邮箱格式不正确", "该用户名已被注册" ] }
内容的提问来源于stack exchange,提问作者DrXSsive
相关产品推荐
相关产品推荐

