Fast-Endpoints集成Results模式实现全局异常处理的技术问题
解决Fast-Endpoints与LanguageExt.Result集成的后置处理器类型问题
要在全局后置处理器中获取Result<MyResponse>对象,核心是对context.Response做安全的类型转换,再根据Result的状态生成对应的HTTP响应。以下是具体实现步骤:
1. 实现全局后置处理器
在后置处理器中,通过模式匹配或类型转换将object?类型的Response转为Result<T>,再处理成功/失败分支:
public class ResultPostProcessor : IPostProcessor { public async Task PostProcessAsync(IPostProcessorContext context, CancellationToken ct) { // 安全匹配Result类型的响应 if (context.Response is Result<object> result) { context.HttpContext.Response.StatusCode = result.Match( success => StatusCodes.Status200OK, failure => failure switch { NotFoundError => StatusCodes.Status404NotFound, ValidationError => StatusCodes.Status400BadRequest, _ => StatusCodes.Status500InternalServerError } ); // 根据结果设置响应内容 await result.MatchAsync( success => context.HttpContext.Response.WriteAsJsonAsync(success, ct), failure => context.HttpContext.Response.WriteAsJsonAsync( new ProblemDetails { Title = failure.Message }, ct) ); // 标记响应已处理,避免Fast-Endpoints默认处理逻辑 context.HttpContext.Response.HasStarted = true; } } }
注:这里假设你定义了NotFoundError、ValidationError等领域错误类型,可根据实际情况调整状态码和响应体。
2. 注册全局后置处理器
在Fast-Endpoints的配置中注册这个后置处理器,确保所有端点都能应用:
builder.Services.AddFastEndpoints(c => { c.PostProcessors.Add<ResultPostProcessor>(); });
3. 简化端点定义
现在端点只需专注于业务逻辑,直接返回Result<MyResponse>即可:
public class MyEndpoint : Endpoint<MyRequest, Result<MyResponse>> { public override void Configure() { Post("/api/my-resource"); AllowAnonymous(); } public override async Task HandleAsync(MyRequest req, CancellationToken ct) { // 仅处理正常路径,错误由领域层返回Result.Failure var response = await _myService.DoBusinessLogic(req); await SendAsync(response); } }
4. 泛型优化(可选)
如果需要支持不同类型的Result<T>,可以实现泛型后置处理器:
public class ResultPostProcessor<T> : IPostProcessor { public async Task PostProcessAsync(IPostProcessorContext context, CancellationToken ct) { if (context.Response is Result<T> result) { // 逻辑同上述非泛型版本,针对T类型处理 } } }
然后在注册时针对特定端点类型添加,或者结合反射自动注册,进一步提升复用性。
内容的提问来源于stack exchange,提问作者John Major
相关产品推荐
相关产品推荐

