首页 > 解决方案 > 使用 ControllerFeatureProvider 禁止特定的 ASP.NET Core 控制器在不同的主机中可用

问题描述

我正在开发一个具有 2 个控制器的应用程序 - 一个 AdminController 和一个 JsonController(基于 ControllerBase)。该应用程序包含 2 个或多个控制器的自主机,但只有 1 个自主机将包含 AdminController - 其他主机将仅包含 JsonController。

我目前正在尝试仅在一个自主机中使用 ControllerFeatureProvider 来禁用 AdminController(并使 JsonController 保持活动状态),但是,如果我实现它,它会禁用两个控制器,即我无法查询它们中的任何一个。我已经确认 IsController 正在为每个有问题的控制器返回真/假。ControllerFeatureProvider 如下所示

public class CustomControllerFeatureProvider : ControllerFeatureProvider
{
    protected override bool IsController(TypeInfo typeInfo)
    {
        if (base.IsController(typeInfo))
        {
            if (typeInfo.Name == nameof(AdminController))
            {
                return false;
            }

            return true;
        }

        return false;
    }
}

启动内容为:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(
                "CorsPolicy",
                builder => builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader());
        });

        services.AddResponseCompression(options =>
        {
            options.Providers.Add<GzipCompressionProvider>();
            options.Providers.Add<BrotliCompressionProvider>();
        });

        services.Configure<GzipCompressionProviderOptions>(options =>
        {
            options.Level = CompressionLevel.Optimal;
        });
        services.Configure<BrotliCompressionProviderOptions>(options =>
        {
            // Found via Fiddler that 'Optimal' is very slow
            options.Level = CompressionLevel.Fastest;
        });
        
        services.AddControllers()
            .ConfigureApplicationPartManager(manager =>
            {
                manager.FeatureProviders.Add(new CustomControllerFeatureProvider());

            })
            .ConfigureApiBehaviorOptions(options =>
            {
                options.SuppressInferBindingSourcesForParameters = true;
                options.SuppressModelStateInvalidFilter = true;

            })
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Ignore;
            });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseResponseCompression();
        app.UseCors("CorsPolicy");
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(name: "JSON API", pattern: "json", defaults: new { controller = "json" });
        });
    }

我已经尝试了各种方法:删除任何其他功能提供程序,特别是将路由映射到 JsonController。我在这里错过了什么吗?

标签: c#asp.net-core

解决方案


不太清楚发生了什么,但现在似乎正在工作。正如评论中提到的 King King 一样,您需要清除任何现有的 FeatureProviders(我确实尝试过但无济于事)。

代码现在很简单:

        services.AddControllers()
            .ConfigureApplicationPartManager(manager =>
            {
                manager.FeatureProviders.Clear();
                manager.FeatureProviders.Add(new CustomControllerFeatureProvider());
            })

因为我的 IsController 方法非常业余,所以现在是:

    protected override bool IsController(TypeInfo typeInfo)
    {
        if (!base.IsController(typeInfo) || typeInfo.Name == nameof(AdminController))
            return false;

        return true;
    }

推荐阅读