Asp.Net Core 3.1环境下如何为Swagger自动生成的控制器类标题添加连字符
实现方案
完全可以在不修改自动生成的swagger.json、不影响自动更新能力的前提下实现需求,核心思路是通过Swashbuckle提供的文档过滤器替换控制器显示名称,无需手动维护swagger.json文件,也不需要将自动生成的swagger.json提交到代码仓库。
步骤1:自定义控制器显示名称属性
首先定义一个特性类,用来给每个控制器配置想要展示的带连字符的名称:
[AttributeUsage(AttributeTargets.Class)] public class SwaggerControllerDisplayNameAttribute : Attribute { public string DisplayName { get; } public SwaggerControllerDisplayNameAttribute(string displayName) { DisplayName = displayName; } }
步骤2:实现Swagger文档过滤器
实现IDocumentFilter接口,在swagger.json生成过程中自动替换控制器标签名称:
using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using Microsoft.AspNetCore.Mvc.Controllers; using System.Linq; using System.Reflection; public class ControllerDisplayNameFilter : IDocumentFilter { public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { // 遍历所有API对应的控制器类型 foreach (var apiDescription in context.ApiDescriptions) { var controllerActionDesc = apiDescription.ActionDescriptor as ControllerActionDescriptor; if (controllerActionDesc == null) continue; // 读取控制器上的自定义显示名称特性 var displayNameAttr = controllerActionDesc.ControllerTypeInfo.GetCustomAttribute<SwaggerControllerDisplayNameAttribute>(); if (displayNameAttr == null) continue; // 替换swagger中对应接口的标签名(也就是Swagger UI上的控制器分组名) foreach (var pathItem in swaggerDoc.Paths.Values) { foreach (var operation in pathItem.Operations.Values) { var oldTagName = operation.Tags.FirstOrDefault(t => t == controllerActionDesc.ControllerName); if (oldTagName != null) { operation.Tags.Remove(oldTagName); operation.Tags.Add(displayNameAttr.DisplayName); } } } } // 标签去重 swaggerDoc.Tags = swaggerDoc.Tags .GroupBy(t => t.Name) .Select(g => g.First()) .ToList(); } }
步骤3:注册过滤器并给控制器配置名称
在Startup.cs的ConfigureServices方法中注册刚才写的过滤器:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "你的API名称", Version = "v1" }); // 注册自定义的控制器名称替换过滤器 c.DocumentFilter<ControllerDisplayNameFilter>(); });
然后给对应控制器加特性即可:
[ApiController] [Route("api/school-admins")] [SwaggerControllerDisplayName("School-Admin")] // 这里配置Swagger UI上显示的名称 public class SchoolAdminController : ControllerBase { [HttpGet("{id}")] public IActionResult Get(int id) { // 你的业务逻辑 return Ok(); } }
后续维护规则
后续新增控制器时,只需要给新控制器添加[SwaggerControllerDisplayName("自定义连字符名称")]特性即可,swagger.json会在每次项目启动/构建时自动生成正确的控制器标题,无需人工修改生成的文件,也不会出现更新冲突问题。
内容的提问来源于stack exchange,提问作者luci
相关产品推荐
相关产品推荐

