繁体   English   中英

有没有办法在 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不是用户友好的名称,因此我想将其更改为用户友好的名称。

大摇大摆的用户界面

ASP.NET Core 6开始,您可以在 Controller 级别上使用TagsAttribute

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

或在行动层面:

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

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

您可以为此使用标签。 默认情况下,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获取控制器名称

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

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

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

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

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

要使其工作,您可能必须添加以下内容:

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

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

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

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

所以,我创建了一个约定类来与控制器 Route 属性一起使用,我们通常在我们的控制器上使用它,然后让 swagger 使用它作为控制器的名称。 好吧,您知道属性上有一个 name 属性,但生成的 swagger 似乎没有使用它。

第 1 步:创建这个类:

当应用程序启动时,它将运行它,如果我的控制器指定了该属性,我将能够在我的控制器上查找 Route 属性,然后使用 name 属性更改控制器的名称。

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 文件,在配置服务中,我们需要在约定列表中注册我们的类。 见下文:

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

第 3 步:在每个控制器的 Route Attribute 中添加 name 属性:

[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 时,您可以看到控制器名称已更改为与路由属性名称属性中的文本相同。

在此处输入图片说明

如果想在控制器/类级别执行此操作,以下是此处的非常有用的摘录

在控制器上使用 [ApiExplorerSettings(GroupName = "Group")]

然后在启动

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

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

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

还要注意的是

swashbuckle 的 5.0.0-beta 现在包含支持返回标签数组的 TagActionsBy 重载。 这应该允许简化上述自定义

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM