仅向 [ApiController] 注释控制器的操作添加操作过滤器?
Add action filter to [ApiController] annotated controller's actions only?
在 Core 之前,当 MVC 和 Web 的控制器 API 是分开的时,很容易在一个框架或另一个框架上定位全局操作。现在 mvcOptions.Filters.Add<T>();
它将应用于您的 MVC 视图呈现操作,并且您是 API-only 操作。
我可以粗略地看到当你使用 [ApiController]
时(docs), you're opted in to several conventions/behaviours, but it's not super clear how/if I could add to that convention easily. Potentially I need to create my own additional ApiBehaviorApplicationModelProvider
, like the one here?我正在寻找更简单的东西,比如 mvcOptions.ApiConvention.Filters.Add(x)
。
另一种方法是让我所有的 API 控制器继承我自己的 ApiControllerBase
并对其进行注释,但如果可能的话,我更愿意扩展约定。
如果不需要 MvcControllerBase
来获得观看效果,那么换个方向也不错。
据我所知,[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
class 中的 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]
属性应用于控制器所在的程序集。如果您还使用视图,则可能不需要它,但值得注意此方法的区别。
在 Core 之前,当 MVC 和 Web 的控制器 API 是分开的时,很容易在一个框架或另一个框架上定位全局操作。现在 mvcOptions.Filters.Add<T>();
它将应用于您的 MVC 视图呈现操作,并且您是 API-only 操作。
我可以粗略地看到当你使用 [ApiController]
时(docs), you're opted in to several conventions/behaviours, but it's not super clear how/if I could add to that convention easily. Potentially I need to create my own additional ApiBehaviorApplicationModelProvider
, like the one here?我正在寻找更简单的东西,比如 mvcOptions.ApiConvention.Filters.Add(x)
。
另一种方法是让我所有的 API 控制器继承我自己的 ApiControllerBase
并对其进行注释,但如果可能的话,我更愿意扩展约定。
如果不需要 MvcControllerBase
来获得观看效果,那么换个方向也不错。
据我所知,[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
class 中的 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]
属性应用于控制器所在的程序集。如果您还使用视图,则可能不需要它,但值得注意此方法的区别。