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

XN1*_*N16 14 c# swagger swagger-ui swashbuckle

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

在下图中,您可以看到swagger-ui页面中显示的两个控制器.这些是在C#代码中命名的,但是我想知道是否有办法改变这里显示的内容?

这主要是因为您可以看到ManagementDashboardWidget不是用户友好名称,所以我想将其更改为用户友好.

招摇的UI

Rau*_*ian 48

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

[Tags("entity")]
[ApiController]
public class DerivedEntitiesController : ControllerBase
{
Run Code Online (Sandbox Code Playgroud)

或在行动层面:

[Tags("entity")]
[HttpPut("entity/{key}")]
public IActionResult PutEntity(Guid key, [FromBody] Entity entity)
{
Run Code Online (Sandbox Code Playgroud)

Swagger 将根据TagsAPI 版本控制进行分组。


ven*_*rik 13

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

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

Get操作现在将放入该组中Test.

如果您希望操作显示在多个组中,则可以添加更多标记.例如:

[SwaggerOperation(Tags = new[] { "Test", "Release1" })]
Run Code Online (Sandbox Code Playgroud)

将把Get在组操作TestRelease1.

  • 这有效,但它仍然将控制器名称作为 UI 中的标记保留,但在其下没有任何操作。例如,假设我有 `ABCController`,但我已将 `[SwaggerOperation(Tags = new[] { "DEF" })]` 添加到所有路由,UI 显示“ABC”和“DEF”,但什么也没有在“ABC”下。我们如何彻底摆脱“ABC”? (2认同)

jta*_*ate 13

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

DisplayNameAttribute在控制器上添加:

[DisplayName("Your New Tag")]
public class YourController : ApiController
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后在 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
    });
Run Code Online (Sandbox Code Playgroud)

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

  • @CodyStott `ControllerName()` 是 [Swagger-Net](https://github.com/heldersepu/Swagger-Net) 库中定义的扩展方法,这是另一个与 Swashbuckle 非常相似的库(这是我假设的您正在使用)。话虽如此,您应该能够使用`apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName` 来获取控制器名称。 (4认同)

Mic*_*out 9

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

options.TagActionsBy(api => new[] { api.GroupName });
Run Code Online (Sandbox Code Playgroud)

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

[ApiExplorerSettings(GroupName = "...")]
Run Code Online (Sandbox Code Playgroud)

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

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

options.DocInclusionPredicate((name, api) => true);
Run Code Online (Sandbox Code Playgroud)

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


Die*_*o B 7

默认情况下,如果我有一个名为 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;
                }
            }

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

第 2 步:Startup.cs:

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

services.AddControllers(o =>
{
   o.Conventions.Add(new ControllerDocumentationConvention());
});
Run Code Online (Sandbox Code Playgroud)

第 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
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

  • 那是非常优雅的。很好的建议! (2认同)