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

.NET Core 2.2迁移至7.0:DefaultFilterProvider继承权限问题求助

修复方案:替代继承内部类DefaultFilterProvider的实现

在.NET Core 3.0及以后的版本中,DefaultFilterProvider被标记为内部类(internal),不再允许外部继承,这就是你迁移后报错的核心原因。下面提供两种可行的替代方案:

方案一:直接实现IFilterProvider接口

放弃继承内部类,自己实现IFilterProvider接口完成动态添加过滤器的逻辑,完全不依赖框架内部类型:

using Microsoft.AspNetCore.Mvc.Filters;

namespace ProjectName.WebAPI.LegacyAuth
{
    public class FilterProviderOption
    {
        public string RoutePrefix { get; set; }
        public AuthorizeFilter Filter { get; set; }
    }

    public class AuthenticationFilterProvider : IFilterProvider
    {
        private readonly FilterProviderOption[] _options;
        public int Order => -1; // 设置执行顺序,确保在默认提供者之前运行

        public AuthenticationFilterProvider(params FilterProviderOption[] options)
        {
            _options = options ?? throw new ArgumentNullException(nameof(options));
        }

        public void OnProvidersExecuting(FilterProviderContext context)
        {
            var routeTemplate = context.ActionContext.ActionDescriptor.AttributeRouteInfo?.Template;
            if (string.IsNullOrEmpty(routeTemplate))
                return;

            var matchingOption = _options.FirstOrDefault(opt => 
                routeTemplate.StartsWith(opt.RoutePrefix, StringComparison.Ordinal));
            
            if (matchingOption?.Filter == null)
                return;

            // 检查过滤器是否已存在,避免重复添加
            var filterExists = context.Results.Any(r => 
                r.Descriptor.Filter == matchingOption.Filter);
            
            if (!filterExists)
            {
                context.Results.Add(new FilterItem(
                    new FilterDescriptor(matchingOption.Filter, FilterScope.Controller)));
            }
        }

        public void OnProvidersExecuted(FilterProviderContext context)
        {
            // 无额外操作,留空即可
        }
    }
}

然后在Program.cs中注册这个自定义提供者:

builder.Services.AddSingleton<IFilterProvider, AuthenticationFilterProvider>(sp =>
{
    // 初始化你的FilterProviderOption配置
    var options = new[]
    {
        new FilterProviderOption
        {
            RoutePrefix = "/api/legacy",
            Filter = new AuthorizeFilter("LegacyAuthPolicy")
        }
    };
    return new AuthenticationFilterProvider(options);
});

方案二:使用端点路由直接绑定过滤器(推荐)

.NET 7更推荐通过端点路由的方式为特定路由范围配置过滤器,这种方式简洁且符合框架设计趋势,无需自定义FilterProvider:

在Program.cs中配置路由时,针对特定前缀的控制器添加过滤器:

// 为所有以/api/legacy开头的路由添加授权过滤器
app.MapControllers()
   .RequireAuthorization("LegacyAuthPolicy")
   .AddEndpointFilter(async (context, next) =>
   {
       // 如需自定义逻辑,可在此添加额外处理
       return await next(context);
   });

// 或者更精确匹配路由前缀
app.MapControllerRoute(
    name: "legacyApi",
    pattern: "api/legacy/{controller}/{action=Index}/{id?}")
   .AddEndpointFilter<LegacyAuthorizeFilter>(); // 替换为你的自定义授权过滤器

关键注意点

  • 移除对Microsoft.AspNetCore.Mvc.Internal的引用,该命名空间下的类型均为框架内部实现,后续版本会持续隐藏。
  • 方案二更贴合.NET 7的设计理念,减少对框架内部细节的依赖,后续版本迁移更顺畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 17:06:05