C# 您是否可以注册Web API ActionFilter而不进行全局注册?

C# 您是否可以注册Web API ActionFilter而不进行全局注册?,c#,asp.net-web-api,C#,Asp.net Web Api,我在许多帖子中看到了如何在全球范围内实现这一点,并在我的代码中实现了这一点。问题是,它在每次调用时都会启动,这不是我想要的,我只希望它在调用我用属性修饰方法的方法时启动: public class MyController : ApiController { [MyAttribute] public void MethodA() { // Do Work - should have called the attribute filter }

我在许多帖子中看到了如何在全球范围内实现这一点,并在我的代码中实现了这一点。问题是,它在每次调用时都会启动,这不是我想要的,我只希望它在调用我用属性修饰方法的方法时启动:

public class MyController : ApiController
{
    [MyAttribute]
    public void MethodA()
    {
        // Do Work - should have called the attribute filter
    }

    public void MethodB()
    {
        // Do Work - should NOT have called the attribute filter
    }
}
这对我来说似乎是非常基本的,而且我遗漏了一些东西,但我能让属性触发的唯一方法是使用
global.asax
GlobalConfiguration.Configuration.Filters.Add(new MyAttribute())在
global.asax
中注册它
这会导致它在向
MethodA
MethodB
发出请求时触发。是否有任何方法可以注册属性并仅在标记它的方法上激发?我尝试过使用
AttributeUsage
但没有效果

EDIT为每个注释添加了属性代码,尽管必须删除内部工作。它正在向所有请求开火

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // Do work
    }
}
编辑11/25 除了下面我接受答案的信息之外,我还想补充一点,以前的开发人员已经删除了默认ActionDescriptorFilterProvider,其中包含需要注释掉的以下代码,以便自定义操作筛选器的默认行为生效:

var providers = GlobalConfiguration.Configuration.Services.GetFilterProviders();
var defaultprovider = providers.First(i => i is ActionDescriptorFilterProvider);

// This line was causing the problem.    
GlobalConfiguration.Configuration.Services.Remove(typeof(System.Web.Http.Filters.IFilterProvider), defaultprovider);
看,上面写得很清楚

获取应用于使用此函数服务的所有请求的筛选器列表 HttpConfiguration实例

但你需要ActionFilter——根据定义

操作筛选器包含在操作之前和之后执行的逻辑 控制器动作执行。例如,您可以使用操作筛选器 实例,以修改控制器操作返回的视图数据

因此,基本上您需要做的是删除

GlobalConfiguration.Configuration.Filters.Add(new MyAttribute());

Global.asax.cs文件中的行。

使用操作或控制器级别的筛选器,您需要使用相同的ConfigureServices方法将其注册为服务:

services.AddScoped<ActionFilterExample>();
services.AddScoped<ControllerFilterExample>();
services.addScope();
services.addScope();
最后,要使用在操作或控制器级别注册的筛选器,需要将其作为服务类型放置在控制器或操作的顶部:

namespace AspNetCore.Controllers
{
    [ServiceFilter(typeof(ControllerFilterExample))]
    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        [ServiceFilter(typeof(ActionFilterExample))]
        public IEnumerable<string> Get()
        {
            return new string[] { "example", "data" };
        }
    }
}
名称空间AspNetCore.Controllers
{
[ServiceFilter(类型(ControllerFilterExample))]
[路由(“api/[控制器]”)]
[ApiController]
公共类TestController:ControllerBase
{
[HttpGet]
[ServiceFilter(类型(ActionFilterExample))]
公共IEnumerable Get()
{
返回新字符串[]{“示例”,“数据”};
}
}
}

这里什么是MyClass?…是的,您可以在控制器的操作上修饰筛选器属性,并且只有那些属性会按照您的期望被调用,但是我看到这里MyClass不是控制器…您应该显示属性的源代码,它也是一个ApiController,更新了代码以反映这一点。@Dan-o为操作过滤器添加了代码。@Kiran Challa是的,这是MVC 3中的工作方式,这是带有WebAPI控制器的MVC 4,我还没有弄清楚如何让它以完全相同的方式工作。嗯,好吧,这接近于为我提供一个答案。我看到在我的OOB示例项目中它是如何工作的。我将更深入地研究过滤器与注册处理程序的交互,并向您报告。如果它给了我答案,我会把这个标记为答案,谢谢。