You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中从ConfigureApplicationPartManager移除单个控制器

如何在ASP.NET Core MVC中移除单个控制器并通过配置控制可用控制器

当然可以仅移除单个控制器,甚至能通过配置文件灵活控制类库中哪些MVC控制器可用,以下是具体实现方案:

1. 配置文件定义允许的控制器

在appsettings.json中添加配置项,指定允许启用的控制器全名(含命名空间):

{
  "AllowedControllers": [
    "YourLibrary.Controllers.HomeController",
    "YourLibrary.Controllers.Api.UserController"
  ]
}

2. 实现配置驱动的控制器过滤

根据你的.NET版本,在启动逻辑中拦截MVC的控制器加载过程,结合配置筛选控制器:

.NET 6+ 示例(替换默认特性提供器)

这种方式更灵活,能完全控制哪些类型被识别为控制器:

var builder = WebApplication.CreateBuilder(args);

// 读取配置中的允许列表
var allowedControllers = builder.Configuration.GetSection("AllowedControllers").Get<string[]>();

builder.Services.AddControllers()
    .ConfigureApplicationPartManager(apm =>
    {
        // 移除默认的控制器特性提供器,替换为自定义实现
        var defaultProvider = apm.FeatureProviders.OfType<ControllerFeatureProvider>().First();
        apm.FeatureProviders.Remove(defaultProvider);
        apm.FeatureProviders.Add(new ConfigurableControllerFeatureProvider(allowedControllers));
    });

var app = builder.Build();

// 中间件配置...

app.Run();

// 自定义控制器特性提供器
public class ConfigurableControllerFeatureProvider : ControllerFeatureProvider
{
    private readonly HashSet<string> _allowedControllers;

    public ConfigurableControllerFeatureProvider(string[] allowedControllers)
    {
        _allowedControllers = new HashSet<string>(allowedControllers ?? Array.Empty<string>(), StringComparer.OrdinalIgnoreCase);
    }

    protected override bool IsController(TypeInfo typeInfo)
    {
        // 先判断是否符合控制器的基础条件
        if (!base.IsController(typeInfo))
            return false;

        // 允许列表为空时默认启用所有控制器,否则仅保留列表内的
        if (_allowedControllers.Count == 0)
            return true;

        return _allowedControllers.Contains(typeInfo.FullName);
    }
}

简化方案:直接过滤已加载的控制器集合

如果不想替换整个特性提供器,也可以在控制器特性注册后直接修改集合:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .ConfigureApplicationPartManager(apm =>
    {
        apm.FeatureRegistered += (feature) =>
        {
            if (feature is ControllerFeature controllerFeature)
            {
                var allowedControllers = builder.Configuration.GetSection("AllowedControllers").Get<string[]>();
                if (allowedControllers?.Any() == true)
                {
                    var allowedSet = new HashSet<string>(allowedControllers, StringComparer.OrdinalIgnoreCase);
                    // 移除不在允许列表中的控制器
                    controllerFeature.Controllers.RemoveAll(ctrl => !allowedSet.Contains(ctrl.FullName));
                }
            }
        };
    });

// 后续启动逻辑...

关键注意事项

  • 必须使用控制器的完整命名空间+类名,避免不同命名空间下的同名控制器被误过滤
  • 建议保留“允许列表为空时启用所有控制器”的逻辑,防止配置错误导致无控制器可用
  • 这种过滤是在MVC加载控制器的早期阶段完成,性能开销极低,比运行时拦截(如ActionFilter)更高效

内容的提问来源于stack exchange,提问作者tris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:40:07