DEV Community

Ashiqul
Ashiqul

Posted on

Ensure ActionExecutionDelegate is invoked from ASP.NET Core filter

Developers might forget to invoke ActionExecutionDelegate from ASP.NET Core filter IAsyncActionFilter.OnActionExecutionAsync. Which is essential for the HTTP request to go through the whole pipeline. So forgetting to invoke ActionExecutionDelegate will essentially terminate the request processing through the pipeline.

For ease I use following abstract base class which just wraps the interface and ennsures ActionExecutionDelegate is being invoked.

public abstract class BaseAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        await OnActionExecutionAsync(context);

        await next();
    }

    protected abstract Task OnActionExecutionAsync(ActionExecutingContext context);
}
Enter fullscreen mode Exit fullscreen mode

Following xunit test verifies that ActionExecutionDelegate will be invoked.

[Fact]
public async Task OnActionExecutionAsync_Should_Invoke_Action_Execution_Delegate()
{
    // Arrange

    // setup fixture (using nuget package AutoFixture)

    var fixture = new Fixture(); 
    fixture.Register(() => new ParameterDescriptor());
    fixture.Customize(new AutoMoqCustomization());

    var hasActionExecutionContextInvoked = false;

    Task<ActionExecutedContext> Next()
    {
        hasActionExecutionContextInvoked = true;

        return Task.FromResult(fixture.Create<ActionExecutedContext>());
    }

    var sut = new SpyBaseAsyncActionFilter();

    // Act

    await sut
        .OnActionExecutionAsync(fixture.Create<ActionExecutingContext>(), Next);

    // Assert

    hasActionExecutionContextInvoked.ShouldBeTrue();
}


public class SpyBaseAsyncActionFilter : BaseAsyncActionFilter
{
    protected override Task OnActionExecutionAsync(ActionExecutingContext context)
    {
        return Task.CompletedTask;
    }
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)