APIController无需标注多ApiVersion属性的版本校验及Swagger兼容方案问询
自定义API版本校验及Swagger兼容实现方案
官方推荐实现路径
你需要的能力官方ASP.NET API版本控制组件已经提供了原生扩展点,无需自行实现IActionConstraint。你之前写的IActionConstraint未触发,是因为版本控制中间件的版本匹配逻辑优先级更高,请求未通过内置校验就会被直接拦截,不会进入Action约束流程。
官方推荐使用IApiVersionProvider扩展点,动态为控制器注入支持的版本列表,具体实现步骤如下:
- 定义自定义版本校验特性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class ValidateApiVersionAttribute : Attribute { // 支持的版本列表可根据业务逻辑从配置、数据库或其他存储动态读取 public IEnumerable<ApiVersion> SupportedVersions { get; } public ValidateApiVersionAttribute() { // 示例:内置TestController对应的版本列表,不同控制器可单独实现对应逻辑 SupportedVersions = new List<ApiVersion> { ApiVersion.Parse("2020-11-01-preview"), ApiVersion.Parse("2020-11-01.1-preview"), ApiVersion.Parse("2021-11-01.2-preview"), ApiVersion.Parse("2021-11-01.3-preview") }; } }
- 实现自定义版本供应器
public class CustomControllerApiVersionProvider : IApiVersionProvider { // 设置优先级高于默认供应器,覆盖原生特性读取逻辑 public int Order => -9999; public void OnProvidersExecuting(ApiVersionProviderContext context) { if (context.ActionDescriptor is not ControllerActionDescriptor controllerDesc) return; // 读取控制器上的自定义版本校验特性 var validateAttr = controllerDesc.ControllerTypeInfo.GetCustomAttribute<ValidateApiVersionAttribute>(); if (validateAttr == null) return; // 将自定义版本列表注入版本控制上下文,官方组件会自动完成校验 context.SupportedApiVersions.UnionWith(validateAttr.SupportedVersions); context.HasValidApiVersions = true; } public void OnProvidersExecuted(ApiVersionProviderContext context) { // 无后置逻辑可留空 } }
- 服务注册配置
services.AddApiVersioning(opt => { // 指定从查询参数apiversion读取版本号 opt.ApiVersionReader = new QueryStringApiVersionReader("apiversion"); opt.ReportApiVersions = true; opt.AssumeDefaultVersionWhenUnspecified = false; }) // 注册自定义版本供应器 .Services.TryAddEnumerable( ServiceDescriptor.Singleton<IApiVersionProvider, CustomControllerApiVersionProvider>() );
完成以上配置后,控制器仅需标记[ValidateApiVersion]特性即可完成版本校验,无需重复添加多个[ApiVersion]特性。
Swagger兼容方案
使用官方配套的API版本探查包即可自动兼容Swagger文档生成,无需额外自定义逻辑:
- 安装NuGet包:
Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer - 注册版本探查服务:
services.AddVersionedApiExplorer(opt => { // 按你的版本格式调整Swagger分组名规则 opt.GroupNameFormat = "yyyy-MM-dd.VV'-preview'"; opt.SubstituteApiVersionInUrl = false; });
- 配置Swagger生成逻辑,自动按支持的版本生成多组文档:
services.AddSwaggerGen(opt => { var versionProvider = services.BuildServiceProvider() .GetRequiredService<IApiVersionDescriptionProvider>(); foreach (var desc in versionProvider.ApiVersionDescriptions) { opt.SwaggerDoc(desc.GroupName, new OpenApiInfo { Title = "业务接口文档", Version = desc.ApiVersion.ToString() }); } });
以上配置完成后,Swagger会自动识别每个控制器的支持版本列表,生成对应版本的接口文档,和原有使用[ApiVersion]特性的效果完全一致。
内容的提问来源于stack exchange,提问作者Divya Malini
相关产品推荐
相关产品推荐

