.NET项目Swagger无法正确显示1.0版本接口信息求助
问题排查:Swagger无法显示API 1.0版本接口信息
问题描述
C# WebAPI项目已定义API版本1.0、1.1和1.2-rc1,所有版本接口均可正常调用,但Swagger文档仅能正确展示1.1和1.2-rc1版本的接口,1.0版本页面提示**"No operations defined in spec!"**。
核心原因
当前Swagger配置仅手动添加了各版本的Swagger文档元信息,但未正确配置接口与对应版本文档的关联规则;同时手动维护版本列表的方式无法与Asp.Versioning自动生成的API版本描述完全匹配,导致Swagger无法识别1.0版本的接口归属。
解决方案
1. 依赖自动生成的API版本描述
通过IApiVersionDescriptionProvider获取Asp.Versioning自动生成的版本信息,替代手动维护版本列表的方式,确保版本名称与接口分组完全一致。
2. 配置接口与Swagger文档的关联规则
添加DocInclusionPredicate,明确每个接口对应的Swagger文档分组,让Swagger能正确将接口归类到对应版本的文档中。
3. 规范API版本定义(可选但推荐)
将版本定义从字符串改为ApiVersion对象,避免字符串解析误差,提升版本管理的严谨性。
代码修改示例
Program.cs 修改
using Asp.Versioning; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerUI; namespace TestSwagger { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddApiVersioning(options => { options.AssumeDefaultVersionWhenUnspecified = false; options.ReportApiVersions = true; options.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader()); }) .AddApiExplorer(options => { options.GroupNameFormat = "'v'VVV"; options.SubstituteApiVersionInUrl = true; }); // 注入IApiVersionDescriptionProvider用于后续配置 builder.Services.AddSwaggerGen((options, sp) => { var apiVersionDescriptionProvider = sp.GetRequiredService<IApiVersionDescriptionProvider>(); // 遍历自动生成的版本描述创建Swagger文档 foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions) { options.SwaggerDoc( description.GroupName, new OpenApiInfo { Version = description.ApiVersion.ToString(), Title = $"A Test API {description.GroupName}", Description = "An dotnet core web api test ", TermsOfService = new Uri("https://localhost/terms"), Contact = new OpenApiContact { Name = "Contact", Url = new Uri("http://localhost/contact") }, License = new OpenApiLicense { Name = "License", Url = new Uri("http://localhost/license") } }); } // 配置接口与Swagger文档的关联规则 options.DocInclusionPredicate((docName, apiDesc) => { var actionApiVersions = apiDesc.ActionDescriptor.EndpointMetadata .OfType<ApiVersionAttribute>() .SelectMany(attr => attr.Versions); return actionApiVersions.Any(v => $"v{v.ToString()}" == docName); }); }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>(); app.UseSwaggerUI(action => { // 使用自动生成的版本描述添加Swagger端点 foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions) { action.SwaggerEndpoint( $"/swagger/{description.GroupName}/swagger.json", $"A small test API {description.GroupName}"); } action.DisplayRequestDuration(); }); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); } } }
DefinedApiVersion.cs 修改(可选)
using Asp.Versioning; using System.Reflection; namespace TestSwagger { public static class DefinedApiVersion { public static readonly ApiVersion V1_0 = new ApiVersion(1, 0); public static readonly ApiVersion V1_1 = new ApiVersion(1, 1); public static readonly ApiVersion V1_2 = new ApiVersion(1, 2, "rc1"); public static List<string> GetAllApiVersionValues() { return typeof(DefinedApiVersion) .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy) .Where(x => x.IsLiteral && x.FieldType == typeof(ApiVersion)) .Select(x => ((ApiVersion)x.GetRawConstantValue()).ToString()) .ToList(); } } }
TestController.cs 修改(对应上面的版本定义)
using Asp.Versioning; using Microsoft.AspNetCore.Mvc; namespace TestSwagger.Controllers { [ApiVersion(DefinedApiVersion.V1_0)] [ApiVersion(DefinedApiVersion.V1_1)] [ApiVersion(DefinedApiVersion.V1_2)] [ApiController] [Route("api/v{version:apiVersion}/[controller]")] public class TestController : ControllerBase { [MapToApiVersion(DefinedApiVersion.V1_0)] [MapToApiVersion(DefinedApiVersion.V1_1)] [MapToApiVersion(DefinedApiVersion.V1_2)] [HttpGet("Method1")] public string Method1() => "1"; [MapToApiVersion(DefinedApiVersion.V1_1)] [MapToApiVersion(DefinedApiVersion.V1_2)] [HttpGet("Method2")] public string Method2() => "2"; [MapToApiVersion(DefinedApiVersion.V1_2)] [HttpGet("Method3")] public string Method3() => "3"; } }
验证
修改后启动项目,Swagger页面中1.0版本应能正常显示Method1接口,与实际调用结果一致。
内容的提问来源于stack exchange,提问作者hg229
相关产品推荐
相关产品推荐

