ApiVersioning库中UseApiBehavior属性的作用与潜在影响
UseApiBehavior属性的作用与风险分析 问题背景
在遗留系统中启用Swagger时,添加了以下配置让端点正常显示:
builder.Services.AddApiVersioning(opt => { opt.UseApiBehavior = false; });
但不清楚该属性的具体作用,不确定它是仅为Swagger暴露端点,还是会改变API端点的行为,同时担心引入破坏性变更。Visual Studio的注释如下:
Gets or sets a value indicating whether to use web API behaviors. True to use web API behaviors; otherwise, false. The default value is true. When this property is set to true, API versioning policies only apply to controllers that remain after the IApiControllerFilter has been applied. When this property is set to false API versioning policies are considers for all controllers. This was default behavior in previous versions
核心作用解析
这个属性不是专门为Swagger设计的,它是ASP.NET API版本控制的核心配置,直接决定版本控制策略的应用范围:
1. 当UseApiBehavior = true(默认值)时
API版本控制策略仅作用于经过IApiControllerFilter筛选后的控制器。
IApiControllerFilter的默认逻辑是:只把继承自ControllerBase的控制器视为“API控制器”,而继承自普通Controller的MVC控制器会被过滤掉。- 换句话说,此时只有API控制器会受到版本规则约束(比如必须指定版本号、路由版本匹配等),MVC控制器完全不受版本控制影响。
2. 当UseApiBehavior = false时
API版本控制策略会作用于系统中所有控制器,无论它是API控制器还是MVC控制器。
- 这是API版本控制早期版本的默认行为,后来为了区分API和MVC场景,才把默认值改成了
true。
为什么设置false能让Swagger显示端点?
遗留系统中可能存在一些非标准的API控制器(比如继承自Controller而非ControllerBase),当UseApiBehavior = true时,这些控制器会被IApiControllerFilter过滤,API版本控制不会处理它们的元数据,导致Swagger无法识别到这些端点的版本信息,最终无法显示。
设置为false后,所有控制器都被纳入版本控制范围,Swagger就能正确抓取到这些端点的元数据,从而正常显示。
破坏性变更风险评估
修改这个属性确实可能引入破坏性变更,需要重点关注以下场景:
- 存在MVC控制器的情况:如果系统中有继承自
Controller的MVC控制器,之前它们不受版本控制约束,设置false后,这些控制器会强制应用版本策略。比如如果你的版本控制要求请求必须携带版本号(如路由参数、Header),那么这些MVC控制器的请求会因为缺少版本信息而返回400/404错误。 - 版本策略冲突:如果旧系统的API版本控制逻辑是基于早期版本(默认
UseApiBehavior = false)设计的,修改回false可能和原有行为一致;但如果是后来升级到新版API版本控制(默认true),修改后会改变原有版本控制的作用范围,可能导致部分API的版本校验逻辑异常。
建议方案
- 先排查控制器类型:统计系统中哪些是
ControllerBase(API控制器)、哪些是Controller(MVC控制器),明确版本控制的目标范围。 - 优先调整过滤器而非修改该属性:如果只是为了让Swagger识别非标准API控制器,可以自定义
IApiControllerFilter的逻辑,把需要暴露给Swagger的控制器纳入筛选范围,而不是直接设置UseApiBehavior = false,避免影响MVC控制器。 - 充分测试:如果必须设置
UseApiBehavior = false,需要全面测试所有控制器的请求,包括API控制器和MVC控制器,验证版本控制策略是否符合预期,没有出现400/404或版本匹配错误。
内容的提问来源于stack exchange,提问作者JKennedy

