【问题标题】:Add action filter to [ApiController] annotated controller's actions only?仅将操作过滤器添加到 [ApiController] 注释控制器的操作?
【发布时间】:2021-12-16 11:28:17
【问题描述】:

在 Core 之前,当 MVC 和 Web API 的控制器是分开的时,很容易在一个框架或另一个框架上定位一个全局操作。现在有了mvcOptions.Filters.Add<T>();,它将应用于您的 MVC 视图呈现操作,而您只是 API 操作。

我可以粗略地看到,当您使用 [ApiController] (docs) 时,您选择了几种约定/行为,但目前尚不清楚如何/是否可以轻松添加到该约定中。可能我需要创建自己的额外ApiBehaviorApplicationModelProvider,比如here?我正在寻找更简单的东西,比如mvcOptions.ApiConvention.Filters.Add(x)

另一种方法是让我的所有 API 控制器继承我自己的 ApiControllerBase 并对其进行注释,但如果可能的话,我更愿意扩展约定。

不用MvcControllerBase 也可以换一种方式来查看。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc


    【解决方案1】:

    据我所知,[ApiController] 约定没有内置的可扩展性,但您可以使用application model 实现您想要的。

    这是一个 IControllerModelConvention 的示例实现,它查找 [ApiController] 属性,您可以填写您的具体实现:

    public class ExampleControllerModelConvention : IControllerModelConvention
    {
        public void Apply(ControllerModel controllerModel)
        {
            if (controllerModel.Attributes.OfType<ApiControllerAttribute>().Any())
            {
                // ...
            }
        }
    }
    

    您可以在 Startup.ConfigureServicesProgram.cs 中为 .NET 6+ 注册此约定:

    // Startup.ConfigureServices
    services.AddControllers(options =>
    {
        options.Conventions.Add(new SampleControllerModelConvention());
    });
    
    // Program.cs
    builder.Services.AddControllers(options =>
    {
        options.Conventions.Add(new SampleControllerModelConvention());
    });
    

    您链接到的ApiBehaviorApplicationModelProvider 类中的IsApiController 方法处理检查的方式略有不同:

    private static bool IsApiController(ControllerModel controller)
    {
        if (controller.Attributes.OfType<IApiBehaviorMetadata>().Any())
        {
            return true;
        }
    
        var controllerAssembly = controller.ControllerType.Assembly;
        var assemblyAttributes = controllerAssembly.GetCustomAttributes();
        return assemblyAttributes.OfType<IApiBehaviorMetadata>().Any();
    }
    

    此实现支持将[ApiController] 属性应用于控制器所在的程序集。如果您还使用视图,则可能不需要此属性,但值得注意的是这种方法的区别。

    【讨论】:

      猜你喜欢
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多