You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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补充接口信息:
    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" }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
    }
    
    然后在Swagger UI中配置多文档切换:
    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中添加该端点即可:
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "我的项目API V1");
        options.SwaggerEndpoint("https://external-api.com/swagger/v1/swagger.json", "外部服务API V1");
    });
    
    这种方式无需在本地生成文档,直接让Swagger UI加载外部规范文件即可渲染交互页面。

内容的提问来源于stack exchange,提问作者user10997800

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:45:35