有没有办法在 swagger-ui 页面中更改控制器的名称?

Is there a way change the Controller's name in the swagger-ui page?

我正在使用 Swashbuckle 在我的 WebApi 项目中启用 swagger 和 swagger-ui。

在下图中,您可以看到我的两个控制器显示在 swagger-ui 页面中。它们的名称与 C# 代码中的名称相同,但我想知道是否有办法更改此处显示的内容?

这主要是因为如您所见,ManagementDashboardWidget 不是用户友好的名称,所以我想将其更改为用户友好的名称。

您可以为此使用标签。默认情况下,Swashbuckle 会为每个操作添加一个带有控制器名称的标签。您可以使用 SwaggerOperationAttribute 覆盖它。例如,下一行将默认标签 Values 替换为标签 Test:

public class ValuesController : ApiController
{
    [SwaggerOperation(Tags = new[] { "Test" })]
    public IHttpActionResult Get()
    {
        // ...
    }
}

Get操作现在将放在组 Test 中。

如果您希望该操作出现在多个组中,您可以添加更多标签。例如:

[SwaggerOperation(Tags = new[] { "Test", "Release1" })]

会将 Get 操作放在组 TestRelease1 中。

我尝试使用 venerik 的答案,但它仍然在 UI 中保留了原始控制器名称以及您指定的新标签。我也不喜欢你必须为每个函数添加一个属性,所以我想出了一个解决方案,你只需要向控制器添加一个属性。有两个步骤:

在控制器上添加DisplayNameAttribute

[DisplayName("Your New Tag")]
public class YourController : ApiController
{
    // ...
}

然后在 Swagger 配置中,您可以使用 GroupActionsBy 函数覆盖基本功能以提取您在该属性中指定的名称:

GlobalConfiguration.Configuration
    .EnableSwagger(c => {
    
        c.GroupActionsBy(apiDesc => {
            var attr = apiDesc
                .GetControllerAndActionAttributes<DisplayNameAttribute>()
                .FirstOrDefault();
                
            // use controller name if the attribute isn't specified
            return attr?.DisplayName ?? apiDesc.ControllerName(); 
        });
        
    })
    .EnableSwaggerUi(c => {
        // your UI config here
    });

ControllerName()Swagger-Net 库中定义的扩展方法。如果您不使用它,您还可以从 apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName

获取控制器名称

如果想在 Controller / Class 级别 执行此操作,以下是 here

中非常有用的摘录

use the [ApiExplorerSettings(GroupName = "Group")] on your controllers

然后在启动

services.AddSwaggerGen(options =>
{
options.SwaggerDoc(version,
    new Info
    {
        Title = name,
        Version = version
    }
);

options.DocInclusionPredicate((_, api) => !string.IsNullOrWhiteSpace(api.GroupName));

options.TagActionsBy(api => api.GroupName);
});

另请注意

5.0.0-beta of swashbuckle now includes an TagActionsBy overload that supports returning an array of tags. This should allow for the above customizations to be simplified

Swashbuckle 版本 5 支持以下选项(用于调用 AddSwaggerGen()):

options.TagActionsBy(api => new[] { api.GroupName });

这应该与控制器或操作上的以下属性结合使用:

[ApiExplorerSettings(GroupName = "...")]

但是,默认情况下组名用于在特定文档中包含操作。所以这可能会导致意外结果(取决于您在调用 options.SwaggerDoc(name, ...) 时对文档的命名)。

要使其正常工作,您可能需要添加以下内容:

options.DocInclusionPredicate((name, api) => true);

此处,对于每个操作,name 是文档的名称,组名在 api.GroupName 中可用。要在文档中包含操作而不考虑其组名,只需 return true。

默认情况下,如果我有一个名为 ShippingController 的控制器,那么 swagger 生成 UI 名称为“Shipping”

我想将控制器的名称更改为更友好的名称或其他语言的名称。我能找到的最好的方法是使用 SwaggerOperation 属性来更改名称,但这有一个限制,即它是一个方法级别的属性,我真的不想在每个方法上指定名称。

因此,我创建了一个约定 class 与我们通常在控制器上使用的控制器 Route 属性一起使用,然后让 swagger 使用它作为控制器的名称。你知道属性上有一个名称 属性 但生成的 swagger 似乎没有使用它。

第 1 步:创建此 class:

当应用程序启动时,它会 运行 这个,我将能够在我的控制器上查找 Route 属性(如果它们具有指定的属性)然后使用名称 属性 进行更改控制器的名称。

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;

namespace RestServices.Configuration.ConfigInstallers.Conventions
{
    public class ControllerDocumentationConvention : IControllerModelConvention
    {
        void IControllerModelConvention.Apply(ControllerModel controller)
        {
            if (controller == null)
                return;

            foreach (var attribute in controller.Attributes)
            {
                if (attribute.GetType() == typeof(RouteAttribute))
                {
                    var routeAttribute = (RouteAttribute)attribute;
                    if (!string.IsNullOrWhiteSpace(routeAttribute.Name))
                        controller.ControllerName = routeAttribute.Name;
                }
            }

        }
    }
}

第 2 步:Startup.cs:

修改StartUp.cs文件,在配置服务中我们需要在约定列表中注册我们的class。见下文:

services.AddControllers(o =>
{
   o.Conventions.Add(new ControllerDocumentationConvention());
});

第 3 步:在每个控制器中添加名称 属性 在路由属性中:

[ApiController]
[ApiVersion("1.0")]
[ApiExplorerSettings(IgnoreApi = false, GroupName = "v1")]
[Route("api/Envios/{version:apiVersion}", Name =  "Envios", Order = 1)]
[Produces("application/json")]
public class ShippingController

现在,当我 运行 应用程序和 swagger 生成时,您可以看到控制器名称已更改为与路由属性名称中的文本相同 属性。

ASP.NET Core 6 开始,您可以在控制器级别使用 TagsAttribute

[Tags("entity")]
[ApiController]
public class DerivedEntitiesController : ControllerBase
{

或行动层面:

[Tags("entity")]
[HttpPut("entity/{key}")]
public IActionResult PutEntity(Guid key, [FromBody] Entity entity)
{

Swagger 将根据 Tags 分组并遵守 API 版本控制。