ASP.NET Core混用Razor Pages与ApiControllers的全局异常处理方法问询
ASP.NET Core 混合Razor Pages与ApiController的全局异常处理方案
核心实现逻辑
通过ASP.NET Core Endpoint路由的元数据判断请求来源:标注了ApiControllerAttribute的端点即为ApiController请求,其余默认按Razor Page请求处理。
具体实现代码
在Program.cs中按如下方式配置UseExceptionHandler中间件:
var builder = WebApplication.CreateBuilder(args); // 注册Razor Pages与Controller服务 builder.Services.AddRazorPages(); builder.Services.AddControllers(); var app = builder.Build(); // 路由匹配中间件,必须放在异常处理中间件之前才能拿到端点元数据 app.UseRouting(); // 全局异常处理中间件 app.UseExceptionHandler(errApp => { errApp.Run(async context => { var exceptionFeature = context.Features.Get<IExceptionHandlerFeature>(); if (exceptionFeature == null) return; // 获取当前匹配的端点 var currentEndpoint = context.GetEndpoint(); // 判断端点是否标注[ApiController]特性 bool isApiRequest = currentEndpoint?.Metadata.GetMetadata<ApiControllerAttribute>() != null; if (isApiRequest) { // API请求返回标准ProblemDetails格式 var problem = new ProblemDetails { Status = StatusCodes.Status500InternalServerError, Title = "服务器内部错误", Detail = app.Environment.IsDevelopment() ? exceptionFeature.Error.ToString() : "请求处理失败,请联系系统管理员" }; context.Response.StatusCode = problem.Status.Value; context.Response.ContentType = "application/problem+json"; await context.Response.WriteAsJsonAsync(problem); return; } // Razor Page请求返回HTML错误页 context.Response.StatusCode = StatusCodes.Status500InternalServerError; context.Response.Redirect("/Error"); }); }); // 其余中间件配置 app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseAuthorization(); app.MapRazorPages(); app.MapControllers(); app.Run();
注意事项
- 中间件顺序必须正确:
UseRouting要放在UseExceptionHandler之前,否则无法获取到匹配后的端点元数据,会导致判断失效。 - 可以额外补充兜底判断逻辑,比如检查请求的
Accept头是否包含application/json、路由前缀是否为/api,和元数据判断结合使用,覆盖更多极端场景。 - 生产环境不要返回异常栈信息,避免泄露服务器敏感信息。
内容的提问来源于stack exchange,提问作者aamd
相关产品推荐
相关产品推荐

