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

.NET 6中如何从ExceptionFilterAttribute获取Controller实例

.NET 6中ExceptionFilterAttribute获取控制器实例的方法

我正在将一个.NET Framework 4.7.2项目迁移至.NET 6。原项目通过ExceptionFilterAttribute调用抛出异常的控制器上的方法,目前仅需先完成迁移,后续再做重构优化。

原.NET Framework中的代码逻辑是通过HttpActionExecutedContext获取控制器实例,转换为ILoggingController后调用指定方法:

public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
    LoggingController = actionExecutedContext.ActionContext.ControllerContext.Controller as ILoggingController;

    if (LoggingController == null)
    {
        throw new InvalidOperationException($"{GetType().Name} can only be used on controllers that implement ILoggingController");
    }

    LoggingController.MethodToCall();

    // 其他逻辑
}

迁移到.NET 6后,原获取控制器实例的方式失效,当前代码只能拿到ControllerActionDescriptor,不清楚如何获取实际的控制器实例:

using Microsoft.AspNetCore.Mvc.Filters;

public class ExcFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        var controller = context.ControllerContext.Controller; // 无法正常工作
        var endpoint = context.HttpContext.GetEndpoint();
        var controllerActionDescriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
        
        base.OnException(context);
    }
}

解决方案

在.NET 6的ExceptionContext中,控制器实例直接存储在context.Controller属性中,不需要通过ControllerContext间接获取。修正后的代码如下:

using Microsoft.AspNetCore.Mvc.Filters;

public class ExcFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        // 直接从context获取控制器实例
        var loggingController = context.Controller as ILoggingController;

        if (loggingController == null)
        {
            throw new InvalidOperationException($"{GetType().Name} can only be used on controllers that implement ILoggingController");
        }

        // 调用控制器上的方法
        loggingController.MethodToCall();

        // 保留基础异常处理逻辑
        base.OnException(context);
    }
}

说明

  • .NET Core/.NET 6的ExceptionContext提供了直接的Controller属性,对应当前执行的控制器实例
  • 类型转换逻辑和原项目保持一致,确保只有实现了ILoggingController的控制器才能使用该过滤器
  • 若不需要额外元数据(如控制器/方法名称),无需通过HttpContext.GetEndpoint()获取ControllerActionDescriptor

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:05:28