asp.net-coreasp.net-core-mvc.net-6.0

How to prevent controllers from loading in ASP.NET Core 6 MVC


I would like to suppress loading of controllers based on a configuration variables available to Startup. I am using .NET 6.0.

I've tried implementing subclasses of either DefaultControllerFactory (inspired by this: How does DefaultControllerFactory Handle Content Requests) or DefaultHttpControllerTypeResolver (inspired by this: How to restrict Asp.net Web API / Owin discovery of controllers by namespace?), but neither of those classes seem to exist in my project.

Is there an updated class I should be using in .NET 6.0 or a different way to restrict loading of specific controllers in .NET 6.0?


Solution

  • You can implements IApplicationModelConvention:

    public class MyControllerConvention : IApplicationModelConvention
    {
        private readonly bool _shouldLoadControllers;
    
        public MyControllerConvention(IConfiguration configuration)
        {
            // Read the config value that decides whether to load controllers or not
            _shouldLoadControllers = configuration.GetValue<bool>("LoadControllers");
        }
    
        public void Apply(ApplicationModel application)
        {
            if (!_shouldLoadControllers)
            {
                //e.g  TestController, controller name is Test
                var controllersToRemove = application.Controllers
                    .Where(c => c.ControllerName == "Test")
                    .ToList();
                //if you want to exclude specific type of controller. eg.TestController inherit from ControllerBase
                //var controllersToExclude = application.Controllers
                     //.Where(c => c.ControllerType.BaseType == typeof(ControllerBase))
                     //.ToList();
                foreach (var controller in controllersToRemove)
                {
                    application.Controllers.Remove(controller);
                }
            }
        }
    }
    

    Register the Custom Convention in Program.cs:

    builder.Services.AddControllers(options =>
    {
        options.Conventions.Add(new MyControllerConvention(builder.Configuration));
    });
    

    You can define a configuration value to control whether the controllers should be loaded or not in appsettings.json:

    {    
      "LoadControllers": false    
    }