0

My .NET Core 3.1 application contains multiple REST endpoints that I splitted in 3 ApiController. I would like to activate the controller from the appsettings.

Each controller is using some DependencyInjection to use the related components that do the job.

All configuration and controller part are running ok, I already filtered out the 'related components' but I struggle to filter out some controller to be created?

Looking at the filter as described here: https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-3.1 is probably the wrong tool since I want to prevent completly the controller class to be created!

I am looking at

    services.AddControllers(options =>
    {
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();   // I only see the default endpoint here
    });

and also on the Swagger generation options but don't yet find the appropriate solution for .NET Core 3.x

Any ideas?

EricBDev
  • 1,279
  • 13
  • 21

1 Answers1

0

I did not find yet a way to disable the controller to be created. So I ended up to implement the injected related component to reply "Api disabled" when called in the endpoints of the controller.

At least, it is possible to remove the controller from the Swagger/OpenApi page. The ApiExplorerSettings on the controller does it on compiling time

[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
[ApiVersion("1")]
[Route("v{version:apiVersion}/myPath1")]
public class MyController
{
}

but this is not an option for me since I want it on runtime. Doing so on runtime is also possible using a DocumentFiler as answered here or there

This is called from the Startup.ConfigureServices when generating the Swagger:

services.AddSwaggerGen(options =>
{
    options.DocumentFilter<OpenApiDocFilter>(flag1, flag2);
}

And the implementation of the filter

public class OpenApiDocFilter : IDocumentFilter
{
    private readonly bool _flag1;
    private readonly bool _flag2;

    public OpenApiDocFilter(bool flag1, bool flag2)
    {
        _flag1 = flag1;
        _flag2 = flag2;
    }

    /// <inheritdoc/>
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        if (swaggerDoc?.Paths == null)
            return;

        var pathsToRemove = swaggerDoc.Paths
            .Where(pathItem => pathItem.Key != null &&
                ((_flag1 && pathItem.Key.Contains("/myPath1", StringComparison.OrdinalIgnoreCase))) ||
                 (_flag2 && pathItem.Key.Contains("/myPath2", StringComparison.OrdinalIgnoreCase))))
            .Select(s => s.Key)
            .ToList();

        foreach (string item in pathsToRemove)
        {
            swaggerDoc.Paths.Remove(item);
        }
    }
}
EricBDev
  • 1,279
  • 13
  • 21