Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filters at controller scope not ran when action scoped filters exist. #62

Open
mciancia8 opened this issue Sep 2, 2021 · 3 comments
Open

Comments

@mciancia8
Copy link

Describe the Bug

Filters that specify a controller and action are the only ones executed and the ones specified for a controller or for all controllers are not ran. I dont' see anything in the documentation that says this since it says that filters are not removed or replaced.

Steps to Reproduce

[RoutePrefix("api/healthcheck")]
    public class HealthCheckController : ApiController
    {
        [HttpGet]
        [Route]
        public IEnumerable<string> Get()
        {
            //throw new InvalidDataException("TEST");
            return new string[] { "value1", "value2" };
        }
    }

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            var builder = new ContainerBuilder();

            builder.RegisterType<HealthCheckController>()
                .InstancePerRequest();

            builder.RegisterType<E1>()
                .AsWebApiActionFilterOverrideFor<HealthCheckController>()
                .SingleInstance();

            builder.RegisterType<E2>()
                .AsWebApiActionFilterOverrideForAllControllers()
                .SingleInstance();

            builder.RegisterType<E3>()
                .AsWebApiActionFilterOverrideFor<HealthCheckController>(x => x.Get())
                .SingleInstance();

            builder.RegisterType<E4>()
                .AsWebApiActionFilterFor<HealthCheckController>()
                .SingleInstance();

            builder.RegisterType<E5>()
                .AsWebApiActionFilterForAllControllers()
                .SingleInstance();

            builder.RegisterType<E6>()
                .AsWebApiActionFilterFor<HealthCheckController>(x => x.Get())
                .SingleInstance();

            builder.RegisterWebApiFilterProvider(config);

            builder.RegisterWebApiModelBinderProvider();

            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        }
    }

    public class E1 : IAutofacContinuationActionFilter
    {
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
            HttpActionContext actionContext,
            CancellationToken cancellationToken,
            Func<Task<HttpResponseMessage>> next)
        {
            Trace.WriteLine("E1 - continue");
            return await next();
        }
    }

    public class E2 : IAutofacContinuationActionFilter
    {
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
            HttpActionContext actionContext,
            CancellationToken cancellationToken,
            Func<Task<HttpResponseMessage>> next)
        {
            Trace.WriteLine("E2 - continue");
            return await next();
        }
    }

    public class E3 : IAutofacContinuationActionFilter
    {
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
            HttpActionContext actionContext,
            CancellationToken cancellationToken,
            Func<Task<HttpResponseMessage>> next)
        {
            Trace.WriteLine("E3 - continue");
            return await next();
        }
    }

    public class E4 : IAutofacContinuationActionFilter
    {
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
            HttpActionContext actionContext,
            CancellationToken cancellationToken,
            Func<Task<HttpResponseMessage>> next)
        {
            Trace.WriteLine("E4 - continue");
            return await next();
        }
    }

    public class E5 : IAutofacContinuationActionFilter
    {
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
            HttpActionContext actionContext,
            CancellationToken cancellationToken,
            Func<Task<HttpResponseMessage>> next)
        {
            Trace.WriteLine("E5 - continue");
            return await next();
        }
    }

    public class E6 : IAutofacContinuationActionFilter
    {
        public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
            HttpActionContext actionContext,
            CancellationToken cancellationToken,
            Func<Task<HttpResponseMessage>> next)
        {
            Trace.WriteLine("E6 - continue");
            return await next();
        }
    }

Expected Behavior

When I run the above code, I get this output in order:

E3 - continue
E6 - continue

and I expect

E1 - continue
E2 - continue
E3 - continue
E4 - continue
E5 - continue
E6 - continue

Dependency Versions

Autofac.WebApi2 6.0.1
Autofac 6.2.0

@tillig
Copy link
Member

tillig commented Sep 2, 2021

As with your other issue, it appears you're registering overrides first, which seems odd. What happens if you register defaults and then overrides?

@mciancia8
Copy link
Author

I just put them first for show since it matched the order of what I expected, I didnt' see a difference in this use case if I changed it to this

builder.RegisterType<E4>()
                .AsWebApiActionFilterFor<HealthCheckController>()
                .SingleInstance();

            builder.RegisterType<E5>()
                .AsWebApiActionFilterForAllControllers()
                .SingleInstance();

            builder.RegisterType<E6>()
                .AsWebApiActionFilterFor<HealthCheckController>(x => x.Get())
                .SingleInstance();

            builder.RegisterType<E1>()
                .AsWebApiActionFilterOverrideFor<HealthCheckController>()
                .SingleInstance();

            builder.RegisterType<E2>()
                .AsWebApiActionFilterOverrideForAllControllers()
                .SingleInstance();

            builder.RegisterType<E3>()
                .AsWebApiActionFilterOverrideFor<HealthCheckController>(x => x.Get())
                .SingleInstance();

@tillig
Copy link
Member

tillig commented Sep 2, 2021

Interesting. Well, looks like something to fix up. If you have a PR, we'd be open to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants