Swagger基于路由属性生成文档及无路由/外部API文档创建方法
问题
现有如下WeatherForecast控制器代码:
using Microsoft.AspNetCore.Mvc; namespace Swagger.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } } }
以及Program.cs中的Swagger基础配置:
using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(options => { }); app.UseSwaggerUI(options => { }); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
请问上述配置对应的Swagger页面是如何生成的?同时,如何为无路由属性的API、非本项目的外部API创建类似的Swagger文档?
回答
一、现有配置的Swagger页面生成流程
整个生成过程分为三个核心阶段:
- 服务注册阶段
builder.Services.AddEndpointsApiExplorer():注册API端点探索服务,自动扫描项目中带有[ApiController]、[HttpGet]等属性的控制器与动作,收集路由规则、请求参数、返回值类型等元数据。builder.Services.AddSwaggerGen():注册Swagger生成服务,基于端点探索器收集到的元数据,生成符合OpenAPI规范的JSON文档(默认可通过/swagger/v1/swagger.json访问)。
- 中间件启用阶段
app.UseSwagger():启动Swagger JSON文档暴露中间件,让客户端能获取到生成的OpenAPI描述文件。app.UseSwaggerUI():启动Swagger UI中间件,读取上述JSON文件,渲染出可视化的交互页面(默认访问路径为/swagger)。
- 元数据扫描与页面渲染
项目启动后,端点探索器自动识别WeatherForecastController的配置:抓取[Route("[controller]")]定义的基础路由/WeatherForecast、[HttpGet]标记的GET请求动作,以及返回的IEnumerable<WeatherForecast>数据结构。Swagger生成器将这些元数据转换为OpenAPI JSON,最终由Swagger UI渲染出包含接口列表、请求示例、响应结构的交互页面,支持直接在页面发起测试请求。
二、扩展场景的Swagger文档生成方案
1. 为无路由属性的API生成Swagger文档
无路由属性的API通常指最小API风格的端点(如app.MapGet("/hello", () => "Hello World")),或未添加路由属性的传统控制器,处理方式如下:
- 最小API场景
确保已注册AddEndpointsApiExplorer(),然后给端点补充元数据标记:app.MapGet("/hello", () => "Hello World") .WithName("GetHello") .WithOpenApi();WithName()指定端点名称,WithOpenApi()显式触发OpenAPI元数据生成,Swagger生成器会自动识别并加入文档。 - 传统控制器无路由属性场景
必须补充[Route]和HTTP动词属性(如[HttpGet]),因为Swagger依赖ASP.NET Core路由系统的元数据来收集接口信息,没有这些属性,端点探索器无法识别接口,自然无法生成Swagger文档。
2. 为非本项目的外部API生成Swagger文档
外部API没有本地代码元数据,可通过两种方式生成Swagger文档:
- 方式一:手动编写OpenAPI描述
在AddSwaggerGen()中添加外部API的文档配置,并通过自定义DocumentFilter补充接口信息:
然后在Swagger UI中配置多文档切换:builder.Services.AddSwaggerGen(c => { // 本项目API文档 c.SwaggerDoc("v1", new OpenApiInfo { Title = "我的项目API", Version = "v1" }); // 外部API文档 c.SwaggerDoc("external-api", new OpenApiInfo { Title = "外部服务API", Version = "v1" }); // 自定义过滤器添加外部API接口 c.DocumentFilter<ExternalApiDocumentFilter>(); }); // 实现DocumentFilter手动定义外部API的接口结构 public class ExternalApiDocumentFilter : IDocumentFilter { public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { swaggerDoc.Paths.Add("/external/users", new OpenApiPathItem { Get = new OpenApiOperation { Summary = "获取用户列表", Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { Description = "成功返回用户列表", Content = new Dictionary<string, OpenApiMediaType> { ["application/json"] = new OpenApiMediaType { Schema = new OpenApiSchema { Type = "array", Items = new OpenApiSchema { Type = "object", Properties = new Dictionary<string, OpenApiSchema> { ["id"] = new OpenApiSchema { Type = "integer" }, ["name"] = new OpenApiSchema { Type = "string" } } } } } } } } } }); } }app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "我的项目API V1"); options.SwaggerEndpoint("/swagger/external-api/swagger.json", "外部服务API V1"); }); - 方式二:导入外部API的OpenAPI规范文件
如果外部API已提供Swagger JSON/YAML文件(如https://external-api.com/swagger/v1/swagger.json),直接在Swagger UI中添加该端点即可:
这种方式无需在本地生成文档,直接让Swagger UI加载外部规范文件即可渲染交互页面。app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "我的项目API V1"); options.SwaggerEndpoint("https://external-api.com/swagger/v1/swagger.json", "外部服务API V1"); });
内容的提问来源于stack exchange,提问作者user10997800
相关产品推荐
相关产品推荐

