ASP.NET Core 8 Web API:为各控制器配置独立Swagger文档页面
实现ASP.NET Core 8 Web API每个控制器独立Swagger页面(基于NSwag)
核心思路
通过给控制器分组、注册多份OpenAPI文档、配置独立Swagger UI实例,实现每个控制器对应专属的Swagger页面,同时支持版本控制。
步骤1:标记控制器分组
给每个控制器添加[ApiExplorerSettings(GroupName)]特性,分组名建议包含版本号(如v1-amazon),方便后续版本区分:
[ApiController] [Route("v1/amazon")] [ApiExplorerSettings(GroupName = "v1-amazon")] public class AmazonController : ControllerBase { [HttpGet("orders")] public IActionResult GetOrders() => Ok(new List<string> { "Order-1", "Order-2" }); } [ApiController] [Route("v1/ebay")] [ApiExplorerSettings(GroupName = "v1-ebay")] public class EBayController : ControllerBase { [HttpGet("items")] public IActionResult GetItems() => Ok(new List<string> { "Item-A", "Item-B" }); } // 示例:V2版本控制器 [ApiController] [Route("v2/amazon")] [ApiExplorerSettings(GroupName = "v2-amazon")] public class AmazonV2Controller : ControllerBase { [HttpGet("orders")] public IActionResult GetOrdersV2() => Ok(new List<object> { new { Id = 1, Status = "Shipped" } }); }
步骤2:注册多份OpenAPI文档
在Program.cs中,为每个分组注册独立的AddOpenApiDocument,通过OperationFilterProcessor过滤仅保留对应分组的端点:
// 注册NSwag服务及多份OpenAPI文档 builder.Services.AddOpenApiDocument(settings => { settings.DocumentName = "v1-amazon"; settings.Title = "Amazon API V1"; settings.Version = "v1"; // 过滤仅包含v1-amazon分组的端点 settings.OperationProcessors.Add(new OperationFilterProcessor(operation => { var apiExplorerAttr = operation.ControllerType.GetCustomAttribute<ApiExplorerSettingsAttribute>(); return apiExplorerAttr?.GroupName == settings.DocumentName; })); }); builder.Services.AddOpenApiDocument(settings => { settings.DocumentName = "v1-ebay"; settings.Title = "EBay API V1"; settings.Version = "v1"; settings.OperationProcessors.Add(new OperationFilterProcessor(operation => { var apiExplorerAttr = operation.ControllerType.GetCustomAttribute<ApiExplorerSettingsAttribute>(); return apiExplorerAttr?.GroupName == settings.DocumentName; })); }); // 注册V2版本文档 builder.Services.AddOpenApiDocument(settings => { settings.DocumentName = "v2-amazon"; settings.Title = "Amazon API V2"; settings.Version = "v2"; settings.OperationProcessors.Add(new OperationFilterProcessor(operation => { var apiExplorerAttr = operation.ControllerType.GetCustomAttribute<ApiExplorerSettingsAttribute>(); return apiExplorerAttr?.GroupName == settings.DocumentName; })); });
步骤3:配置独立Swagger UI实例
为每个OpenAPI文档配置单独的UseSwaggerUi3中间件,指定专属访问路径和文档源,同时禁用顶部文档选择框避免混淆:
// 启用OpenAPI文档生成 app.UseOpenApi(); // 配置Amazon V1专属Swagger页面 app.UseSwaggerUi3(options => { options.Path = "/v1/swagger/amazon"; options.DocumentPath = "/swagger/v1-amazon/swagger.json"; options.DocumentTitle = "Amazon API V1"; options.DisableTopBar = true; // 隐藏顶部文档选择下拉框 }); // 配置EBay V1专属Swagger页面 app.UseSwaggerUi3(options => { options.Path = "/v1/swagger/ebay"; options.DocumentPath = "/swagger/v1-ebay/swagger.json"; options.DocumentTitle = "EBay API V1"; options.DisableTopBar = true; }); // 配置Amazon V2专属Swagger页面 app.UseSwaggerUi3(options => { options.Path = "/v2/swagger/amazon"; options.DocumentPath = "/swagger/v2-amazon/swagger.json"; options.DocumentTitle = "Amazon API V2"; options.DisableTopBar = true; });
访问效果
- Amazon V1文档:
http://localhost:<端口>/v1/swagger/amazon - EBay V1文档:
http://localhost:<端口>/v1/swagger/ebay - Amazon V2文档:
http://localhost:<端口>/v2/swagger/amazon
每个页面仅展示对应控制器的端点,完全独立。
生成专属ApiClient
使用NSwag CLI针对指定文档生成ApiClient:
# 生成Amazon V1客户端 nswag openapi2csclient /input:http://localhost:<端口>/swagger/v1-amazon/swagger.json /output:AmazonApiClientV1.cs # 生成EBay V1客户端 nswag openapi2csclient /input:http://localhost:<端口>/swagger/v1-ebay/swagger.json /output:EBayApiClientV1.cs
内容的提问来源于stack exchange,提问作者Junaid
相关产品推荐
相关产品推荐

