You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中根据异常类型返回特定错误响应?

问题描述

现有如下ASP.NET Core控制器端点:

[HttpGet]
public IActionResult Get()
{
    var resource = _myService.GetSomeResource();
    return Ok(resource);
}

其中GetSomeResource方法会调用VerifyCallerHasAccess校验调用方身份:

public SomeResourceModel GetSomeResource()
{
  _securityVerifier.VerifyCallerHasAccess();

  // 获取资源逻辑

  return resource;
}

当调用方无资源访问权限时,VerifyCallerHasAccess会抛出如下异常:

throw new SecurityException($"User does not have access to this resource");

当前默认返回500错误,希望控制器遇到该类型异常时自动返回403错误,且不想手动添加try/catch。此外,端点已使用.NET授权体系,此处校验是对接外部安全服务验证资源权限。请问能否注册异常与HTTP响应码的映射?若可以,具体如何实现?

解决方案

完全可以实现异常与HTTP响应码的映射,下面提供两种常用的无侵入式实现方式:

方式一:自定义异常过滤器(ExceptionFilterAttribute)

这种方式基于MVC过滤器管道,专门针对控制器/Action抛出的异常做处理:

  1. 创建自定义过滤器类
public class SecurityExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // 判断是否是目标异常类型
        if (context.Exception is SecurityException)
        {
            // 返回403禁止访问结果
            context.Result = new ForbidResult();
            // 标记异常已处理,避免后续默认处理返回500
            context.ExceptionHandled = true;
        }
    }
}
  1. 注册过滤器
    • 全局注册:在Program.cs中配置,对所有控制器生效
      builder.Services.AddControllers(options =>
      {
          options.Filters.Add<SecurityExceptionFilter>();
      });
      
    • 局部注册:仅对特定控制器或Action生效,直接在目标控制器/Action上添加特性
      [SecurityExceptionFilter]
      [HttpGet]
      public IActionResult Get()
      {
          // 原有逻辑不变
      }
      

方式二:全局异常处理中间件

这种方式作用于整个请求管道,能捕获所有环节抛出的异常:
在Program.cs中配置UseExceptionHandler中间件:

app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        var exceptionFeature = context.Features.Get<IExceptionHandlerPathFeature>();
        var exception = exceptionFeature?.Error;

        if (exception is SecurityException)
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            context.Response.ContentType = "application/json";
            // 返回自定义响应内容,也可以直接返回空响应
            await context.Response.WriteAsJsonAsync(new 
            { 
                Message = "无资源访问权限",
                StatusCode = 403
            });
        }
        // 可扩展添加其他异常类型的处理逻辑
    });
});

两种方式的选择

  • 若只需要处理控制器层抛出的异常,优先用自定义过滤器,更贴合MVC场景;
  • 若需要捕获整个请求管道(比如中间件层)的异常,选择全局异常中间件。

内容的提问来源于stack exchange,提问作者Andrio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:10:53