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

时间:2016-05-06 15:29:14

标签: c# swagger swagger-ui swashbuckle

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

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

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

swagger-ui

5 个答案:

答案 0 :(得分:10)

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

替换默认标记Values
public class ValuesController : ApiController
{
    [SwaggerOperation(Tags = new[] { "Test" })]
    public IHttpActionResult Get()
    {
        // ...
    }
}

Get操作现在将放入组Test

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

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

会将Get操作放入群组TestRelease1

答案 1 :(得分:3)

Swashbuckle的版本5支持以下选项(将在对AddSwaggerGen()的调用中使用):

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

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

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

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

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

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

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

答案 2 :(得分:2)

我尝试使用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
    });

答案 3 :(得分:1)

如果要在控制器/类级别上执行此操作,则以下摘录自here

  

在控制器上使用[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重载,它支持返回标签数组。这应该可以简化上述自定义

答案 4 :(得分:0)

默认情况下,如果我有一个名为ShippingController的控制器,则摇摇晃晃生成的用户界面名称为“发货”

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

因此,我创建了一个与控制器Route属性一起使用的约定类,该类通常在我们的控制器上使用,然后大胆地使用它作为控制器的名称。好吧,您知道该属性上有一个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文件,并在配置服务中,我们需要在Conventions列表中注册我们的类。见下文:

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

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

enter image description here