.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
相关产品推荐
相关产品推荐

