.NET 6 MVC中如何基于配置阻止控制器加载?
在.NET 6中基于配置抑制控制器加载的解决方案
你提到的DefaultControllerFactory和DefaultHttpControllerTypeResolver是旧版ASP.NET Web API(非Core)的类,在ASP.NET Core(包括.NET 6)中已被替换,所以找不到是正常的。以下是几种在.NET 6中实现按需加载控制器的实用方法:
方法一:自定义IControllerFeatureProvider控制控制器发现
这是最直接的方式,通过实现IControllerFeatureProvider来决定哪些控制器被系统加载:
- 创建自定义特性提供者类:
using Microsoft.AspNetCore.Mvc.Controllers; using System.Reflection; public class ConfigurableControllerFeatureProvider : IControllerFeatureProvider { private readonly IConfiguration _configuration; public ConfigurableControllerFeatureProvider(IConfiguration configuration) { _configuration = configuration; } public bool IsController(TypeInfo typeInfo) { // 先校验基础控制器类型规则 if (!typeof(ControllerBase).IsAssignableFrom(typeInfo) || !typeInfo.IsClass || typeInfo.IsAbstract) { return false; } // 从配置读取需要禁用的控制器名称列表(配置键示例:DisabledControllers) var disabledControllers = _configuration.GetSection("DisabledControllers").Get<string[]>() ?? Array.Empty<string>(); // 判断当前控制器是否在禁用列表中(忽略大小写匹配) return !disabledControllers.Contains(typeInfo.Name, StringComparer.OrdinalIgnoreCase); } }
- 在
Program.cs中注册自定义提供者:
var builder = WebApplication.CreateBuilder(args); // 注册控制器服务,替换默认的控制器特性提供者 builder.Services.AddControllers() .ConfigureApplicationPartManager(apm => { // 移除默认的ControllerFeatureProvider var defaultProvider = apm.FeatureProviders.First(f => f is ControllerFeatureProvider); apm.FeatureProviders.Remove(defaultProvider); // 添加自定义的配置驱动提供者 apm.FeatureProviders.Add(new ConfigurableControllerFeatureProvider(builder.Configuration)); }); var app = builder.Build(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
方法二:特性标记+配置开关实现细粒度控制
如果需要针对单个控制器设置独立的启用开关,可以用自定义特性配合配置:
- 定义自定义条件特性:
[AttributeUsage(AttributeTargets.Class)] public class ConditionalControllerAttribute : Attribute { public string ConfigKey { get; } public ConditionalControllerAttribute(string configKey) { ConfigKey = configKey; } }
- 在目标控制器上标记特性:
[ConditionalController("EnableAdminController")] public class AdminController : ControllerBase { // 控制器逻辑... }
- 修改特性提供者的判断逻辑:
public bool IsController(TypeInfo typeInfo) { if (!typeof(ControllerBase).IsAssignableFrom(typeInfo) || !typeInfo.IsClass || typeInfo.IsAbstract) { return false; } // 检查是否存在ConditionalController特性 var conditionalAttr = typeInfo.GetCustomAttribute<ConditionalControllerAttribute>(); if (conditionalAttr != null) { // 读取配置值,配置不存在时默认启用控制器 return _configuration.GetValue<bool>(conditionalAttr.ConfigKey, true); } // 无特性标记的控制器默认启用 return true; }
方法三:通过应用部件排除整个程序集/类型
如果需要禁用的控制器集中在某个独立程序集,可以直接排除该程序集:
builder.Services.AddControllers() .ConfigureApplicationPartManager(apm => { // 定位要排除的程序集 var targetAssembly = typeof(AdminController).Assembly; var partToRemove = apm.ApplicationParts.First(p => p is AssemblyPart part && part.Assembly == targetAssembly); apm.ApplicationParts.Remove(partToRemove); });
补充说明
- 配置示例(可放在
appsettings.json中):
{ "DisabledControllers": ["AdminController", "TestController"], "EnableAdminController": false }
- 以上方法均为启动时静态筛选控制器;如果需要运行时动态启用/禁用,可考虑使用中间件或授权策略拦截请求。
内容的提问来源于stack exchange,提问作者Greg Graham
相关产品推荐
相关产品推荐

