仅将操作过滤器添加到 [ApiController] 注释控制器的操作?
Posted
技术标签:
【中文标题】仅将操作过滤器添加到 [ApiController] 注释控制器的操作?【英文标题】:Add action filter to [ApiController] annotated controller's actions only? 【发布时间】: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
也可以换一种方式来查看。
【问题讨论】:
【参考方案1】:据我所知,[ApiController]
约定没有内置的可扩展性,但您可以使用application model 实现您想要的。
这是一个 IControllerModelConvention
的示例实现,它查找 [ApiController]
属性,您可以填写您的具体实现:
public class ExampleControllerModelConvention : IControllerModelConvention
public void Apply(ControllerModel controllerModel)
if (controllerModel.Attributes.OfType<ApiControllerAttribute>().Any())
// ...
您可以在 Startup.ConfigureServices
或 Program.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]
属性应用于控制器所在的程序集。如果您还使用视图,则可能不需要此属性,但值得注意的是这种方法的区别。
【讨论】:
以上是关于仅将操作过滤器添加到 [ApiController] 注释控制器的操作?的主要内容,如果未能解决你的问题,请参考以下文章