ASP.NET Core 6 Web API:自定义基控制器错误处理方法未执行问题
问题原因
基控制器BaseController上标注的[Route("api/[controller]")]路由前缀会被所有继承它的子类控制器(比如ValuesController)继承。当UseExceptionHandler尝试匹配根路径的/error-development或/error时,基类中的错误处理方法实际路由会被合并为api/[controller]/error-development(例如api/values/error-development),和UseExceptionHandler指定的根路径不匹配,因此无法触发执行。
解决方案
有两种常见修复方式:
方式一:将路由前缀移至子类控制器
移除基控制器上的[Route("api/[controller]")],将其添加到每个子类控制器上:
// BaseController.cs [ApiController] public class BaseController : ControllerBase { [ApiExplorerSettings(IgnoreApi = true)] [Route("/error-development")] public IActionResult HandleErrorDevelopment([FromServices] IHostEnvironment hostEnvironment) { Debug.WriteLine("hiiiiiiiiiiiiiiii"); if (!hostEnvironment.IsDevelopment()) { return NotFound(); } var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>()!; return Problem( detail: exceptionHandlerFeature.Error.StackTrace, title: exceptionHandlerFeature.Error.Message); } [ApiExplorerSettings(IgnoreApi = true)] [Route("/error")] public IActionResult HandleError() => Problem(); }
// ValuesController.cs [Route("api/[controller]")] public class ValuesController : BaseController { [HttpGet] public IEnumerable<string> Get() { throw new Exception("Sample exception."); } }
方式二:为错误处理方法指定绝对路由并设置优先级
保留基控制器的路由前缀,但给错误处理方法的[Route]设置Order = int.MinValue,确保绝对路由优先于基类的路由前缀:
// BaseController.cs [Route("api/[controller]")] [ApiController] public class BaseController : ControllerBase { [ApiExplorerSettings(IgnoreApi = true)] [Route("/error-development", Order = int.MinValue)] public IActionResult HandleErrorDevelopment([FromServices] IHostEnvironment hostEnvironment) { Debug.WriteLine("hiiiiiiiiiiiiiiii"); if (!hostEnvironment.IsDevelopment()) { return NotFound(); } var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>()!; return Problem( detail: exceptionHandlerFeature.Error.StackTrace, title: exceptionHandlerFeature.Error.Message); } [ApiExplorerSettings(IgnoreApi = true)] [Route("/error", Order = int.MinValue)] public IActionResult HandleError() => Problem(); }
通过以上任意一种方式,/error-development和/error都会作为根路径路由生效,UseExceptionHandler就能正确匹配到对应的错误处理方法。
内容的提问来源于stack exchange,提问作者Always Learning
相关产品推荐
相关产品推荐

