当前位置: 首页 > news >正文

从 .NET 8 升到 .NET 10,我的 Swagger JWT 认证代码“编译不过“了

一、问题是什么

把项目从 ASP.NET Core 8.0 升级到 10.0,同时把Swashbuckle.AspNetCore从 6.x/7.x 升级到 10.x 之后,原本在 .NET 8 下运行了很久、配置 Swagger JWT 认证的代码突然编译报错:

// .NET 8 时代的写法,升级后编译报错builder.Services.AddSwaggerGen(options=>{options.AddSecurityDefinition("Bearer",newOpenApiSecurityScheme(){Name="Authorization",Type=SecuritySchemeType.ApiKey,In=ParameterLocation.Header,Scheme="Bearer",BearerFormat="JWT",Description="请输入Bearer token",});// 报错点:AddSecurityRequirement 的参数类型不匹配options.AddSecurityRequirement(newOpenApiSecurityRequirement(){{newOpenApiSecurityScheme{Reference=newOpenApiReference(){Type=ReferenceType.SecurityScheme,Id="Bearer"},Scheme="Bearer",Name="Bearer",In=ParameterLocation.Header,},newList<string>()}});});

编译器给出的错误是:

实参类型 “Microsoft.OpenApi.OpenApiSecurityRequirement” 不可分配给形参类型 “System.Func<Microsoft.OpenApi.OpenApiDocument,Microsoft.OpenApi.OpenApiSecurityRequirement>”

翻译过来就是一句话:AddSecurityRequirement方法要的参数类型变了——以前直接传一个OpenApiSecurityRequirement对象就行,现在它要的是一个"委托",一个接收OpenApiDocument、返回OpenApiSecurityRequirement的函数。

二、为什么会变

这不是 Swashbuckle 团队随手改的一个签名,根子在更底层的依赖上。

Swashbuckle.AspNetCore 从诞生起就没有自己造 OpenAPI 对象模型的轮子,而是直接依赖并暴露微软官方的Microsoft.OpenApi(也就是 OpenAPI.NET)库里的类型,比如OpenApiSecuritySchemeOpenApiSecurityRequirement这些,都是直接从Microsoft.OpenApi命名空间里"透传"出来给使用者的。

从 ASP.NET Core 10 开始,如果使用 Microsoft.AspNetCore.OpenApi 这个 NuGet 包,就依赖 Microsoft.OpenApi v2 以上的版本。Swashbuckle.AspNetCore 10.x 为了能在 .NET 10 上顺畅工作,也同步把底层依赖升级到了Microsoft.OpenApiv2。

问题就出在这次大版本升级上——Swashbuckle.AspNetCore 9.x 依赖的是 OpenAPI.NET 1.x,那个版本里 OpenApiSecurityScheme 还带着 Reference 属性,能直接引用一个已定义的安全方案;而 OpenAPI.NET 2.0 引入了破坏性的 API 变更Reference这种"先定义、再引用"的老写法被去掉了,取而代之的是一套新的引用类型体系,同时AddSecurityRequirement的方法签名也顺势改成了接收委托的形式,方便你在委托里拿到完整的OpenApiDocument上下文去动态构建安全要求。

一句话总结这次升级的因果链:

ASP.NET Core 10 内置 OpenAPI 能力依赖 Microsoft.OpenApi v2 → Swashbuckle.AspNetCore 10.x 跟进依赖 Microsoft.OpenApi v2 → OpenAPI.NET v2 是破坏性升级,砍掉了OpenApiSecurityScheme.Reference→ 旧的 JWT 认证配置代码全部编译不过。

如果你在 GitHub 上翻 Swashbuckle 的 issue 区,会发现这不是个例,从 401 未授权到编译报错,升级到 .NET 10 后 AddSecurityRequirement 编译失败、即便改对了签名 [Authorize] 接口依然返回 401 的情况都有不少人踩过坑。

三、怎么解决

解决思路就是照着新签名走:把原来直接传对象,改成传一个委托;把原来靠Reference属性引用安全方案,改成用新的OpenApiSecuritySchemeReference类型直接构造引用。

builder.Services.AddSwaggerGen(options=>{// 定义部分基本不变,只是去掉了 new OpenApiSecurityScheme() 后面多余的括号写法差异options.AddSecurityDefinition("Bearer",newOpenApiSecurityScheme{Name="Authorization",In=ParameterLocation.Header,Type=SecuritySchemeType.ApiKey,Scheme="Bearer",BearerFormat="JWT",Description="请输入Bearer token"});// 关键变化:AddSecurityRequirement 现在接收一个委托// document 参数就是当前正在生成的 OpenApiDocument,// 用它构造出的 OpenApiSecuritySchemeReference 能正确关联到上面定义的 "Bearer" 安全方案options.AddSecurityRequirement(document=>newOpenApiSecurityRequirement(){{newOpenApiSecuritySchemeReference("Bearer",document,null){Description="JWT授权",},newList<string>()}});});

改动其实只有两处:

  1. AddSecurityRequirement的参数从对象变成了Func<OpenApiDocument, OpenApiSecurityRequirement>。所以外面要包一层document => new OpenApiSecurityRequirement() { ... }document参数由 Swashbuckle 在生成文档时自动传入,不需要我们手动构造。
  2. 不再用new OpenApiSecurityScheme { Reference = ... }这种"裸对象 + Reference 属性"的方式引用已定义的安全方案,改用OpenApiSecuritySchemeReference("Bearer", document, null)直接构造一个引用类型,第一个参数是AddSecurityDefinition时注册的方案名(这里要保证大小写完全一致,否则引用会失效,页面上锁头图标点了也没反应),第二个参数是当前文档,第三个参数是可选的描述覆盖(传null即可)。

改完之后重新编译、启动项目,Swagger UI 右上角的 “Authorize” 按钮依然能正常弹出输入框,粘贴Bearer xxx之后所有带[Authorize]的接口都能正常带上认证头,行为和 .NET 8 时代完全一致。

四、给同样在升级路上的你提个醒

如果你的项目里除了 JWT 认证配置,还用到了 Swashbuckle 的IDocumentFilterIOperationFilter里手动构造OpenApiSecurityScheme、引用其他 Schema 等写法,升级到 10.x 时也大概率会踩到同样的坑——本质都是Microsoft.OpenApiv1 到 v2 的破坏性变更。建议的排查顺序是:

  1. 编译报错先别急着改代码,看清楚报错信息里到底是"类型不匹配"还是"成员不存在",前者多半是方法签名变了(比如这次的AddSecurityRequirement),后者多半是属性被移除了(比如这次的Reference)。
  2. 官方有专门的 v10 迁移文档,遇到编译不过的地方先去对照一遍,能省掉很多试错时间。
  3. 升级路径上如果条件允许,先升到 Swashbuckle.AspNetCore 9.0.6 再升 10.x,官方也建议这样过渡,能减少一次性踩坑的数量。

技术栈的版本号往前走一位,看着只是小版本变化,但只要底层依赖发生了破坏性升级,暴露在外层的 API 就都得跟着变。遇到这种"编译不过"的报错,与其猜,不如先搞清楚它到底依赖了谁、那个"谁"又发生了什么变化——这次的排查思路,希望对同样在做 .NET 10 升级的你有用。

http://www.jsqmd.com/news/1265513/

相关文章:

  • 2026 年新消息:思茅到忻州救援拖车公司联系方式,被困时,这台设备如何逆转绝境? - 品质体验官
  • C++ 条件变量信号丢失与虚假唤醒:成因与解决方案
  • 2026年7月S型MBBR填料/循环水养殖MBBR填料行业靠谱厂家_桐乡市小老板特种塑料制品有限公司 - 行业平台推荐
  • ARM架构下银河麒麟V10部署Kubernetes集群实战
  • 设备驱动开发中的资源仲裁与转换机制解析
  • 给 Agent 一把懂数据库的钥匙:KEMCC 如何支撑下一代智能运维
  • Vue3与UE4像素流送深度集成:打造可交互数字孪生看板
  • 2026实测:豆包即梦图片水印去除方法 水印设置入口教程
  • AI商业落地:大模型、Agent与MCP实战解析
  • AI如何解决学术开题三大痛点:选题、文献与方法
  • 集合(泛型Set数据结构)
  • P1328 [NOIP 2014 提高组] 生活大爆炸版石头剪刀布
  • TI CC13x2/CC26x2硬件加密加速器:架构、配置与低功耗实战
  • 2026 年现阶段四子王旗热门的顺灰管铸件厂家供应厂家综合实力解析,别再为铸件发愁!这款产品如何颠覆你的生产成本? - 品质体验官
  • 光伏阵列故障诊断:GUAN网络的小样本解决方案
  • Windows 11下绕过Defender提取RDP凭据的技术解析
  • 2026年7月铣床/龙门加工中心机厂家推荐榜单_成都新台鸿机械设备有限公司 - 品牌宣传支持者
  • Unity项目Live2D模型提取全流程:从AssetBundle到Cubism工程
  • Docker部署Vue项目的完整指南与实践
  • Agent面试详解(下):评测、安全与落地判断
  • Mac mini配置OpenClaw实现自动化办公全攻略
  • 基于Qwen3-Max的电气图纸智能评审系统设计与实践
  • 【Bug已解决】Detail: removal of `.peft_config` when performing `.unload()`? 解决方案
  • 2026实测豆包去水印方法 手机电脑图片视频通用教程
  • 苹果设备iCloud激活锁免费绕过工具:applera1n使用指南
  • 【Bug已解决】CoRDA initialization lacks support for Conv1D layers in older models like GPT-2 解决方案.md
  • 2026年7月家具沙发与床垫编织袋/塑料编织袋厂家推荐_广东锐威新材料科技有限公司 - 行业平台推荐
  • 深入理解进程地址空间与内存管理机制
  • 提示词工程化:AI落地中的高效实践与架构平衡
  • SpringAIAlibab智能客服系统:毫秒级响应与高准确率实践