Recently a question was asked on Stack Overflow about the ability to hide particular controllers from Swagger documentation: https://stackoverflow.com/q/60667324/1658906. I wrote an answer with the first method that I'm aware of:

[ApiExplorerSettings(IgnoreApi = true)]
public class TestApiController : ControllerBase
{
}

By adding this attribute on a controller or action and specifying IgnoreApi = true, it gets hidden from auto-generated documentation.

However, this user has to apply this to around 80 controllers. While applying this attribute probably would not take that long even then, I felt like there should be a more automated way to do this.

Action model conventions

ASP.NET MVC Core has long supported "conventions". By creating conventions, you can modify how MVC works. E.g. add action filters based on some logic.

I made a sample project on GitHub to explore the usage of conventions for the purpose of hiding actions from documentation: https://github.com/juunas11/AspNetCoreHideRoutesFromSwagger.

The controller we want to hide looks like this:

[ApiController]
[Route("[controller]")]
public class SecondController : ControllerBase
{
    [HttpGet]
    public IActionResult Test()
    {
        return Ok(new { Something = "A" });
    }
}

First, I tried hiding the controller with a controller model convention:

public class ControllerHidingConvention : IControllerModelConvention
{
    public void Apply(ControllerModel controller)
    {
        if (controller.ControllerName == "Second")
        {
            controller.ApiExplorer.IsVisible = false;
        }
    }
}

And register it in ConfigureServices:

services.AddControllers(o =>
{
    o.Conventions.Add(new ControllerHidingConvention());
});

But this does not work. As I found out, setting ApiExplorer.IsVisible = false on the controller model makes no difference. The setting must be applied on the action models.

So we could modify the controller convention to loop through the action models. That does actually work, you can see an example of it in the sample app.

However, I thought an action model convention looked cleaner:

public class ActionHidingConvention : IActionModelConvention
{
    public void Apply(ActionModel action)
    {
        // Replace with any logic you want
        if (action.Controller.ControllerName == "Second")
        {
            action.ApiExplorer.IsVisible = false;
        }
    }
}

And register it in ConfigureServices:

services.AddControllers(o =>
{
    o.Conventions.Add(new ActionHidingConvention());
});

This way that particular controller's actions are hidden. You can use any logic you want to decide whether an action should be visible.

Links