简体   繁体   English

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

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

I'm using Swashbuckle to enable the use of swagger and swagger-ui in my WebApi project.我正在使用 Swashbuckle 在我的 WebApi 项目中启用 swagger 和 swagger-ui。

In the following image you can see two of my controllers shown in the swagger-ui page.在下图中,您可以看到我的两个控制器显示在 swagger-ui 页面中。 These are named as they are in the C# code, however I was wondering if there was a way to change what is shown here?这些在 C# 代码中被命名,但是我想知道是否有办法改变这里显示的内容?

This is mainly because as you can see ManagementDashboardWidget is not a user friendly name, so I want to change it to be user friendly.这主要是因为如您所见, ManagementDashboardWidget不是用户友好的名称,因此我想将其更改为用户友好的名称。

大摇大摆的用户界面

Starting with ASP.NET Core 6 , you can use the TagsAttribute either on Controller level:ASP.NET Core 6开始,您可以在 Controller 级别上使用TagsAttribute

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

or on Action level:或在行动层面:

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

Swagger will group according to the Tags and respect API Versioning. Swagger 将根据Tags分组并遵守 API 版本控制。

You can use tags for that.您可以为此使用标签。 By default Swashbuckle adds a tag with the name of the controller to every operation.默认情况下,Swashbuckle 会为每个操作添加一个带有控制器名称的标签。 You can override that with the SwaggerOperationAttribute .您可以使用SwaggerOperationAttribute覆盖它。 For instance, the next line replaces the default tag, Values, with the tag Test:例如,下一行将默认标签 Values 替换为标签 Test:

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

The Get operation will now be put in the group Test . Get操作现在将放在Test组中。

If you want the operation to appear in multiple groups you can add more tags.如果您希望操作出现在多个组中,您可以添加更多标签。 For instance:例如:

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

will put the Get operation in the groups Test and Release1 .将把Get操作放在TestRelease1组中。

I tried using venerik's answer, but it still kept the original controller name in the UI along with the new tag that you specify.我尝试使用 venerik 的答案,但它仍然在 UI 中保留了原始控制器名称以及您指定的新标签。 I also didn't like that you had to add an attribute to every function, so I came up with a solution where you only have to add an attribute to the controller.我也不喜欢你必须为每个函数添加一个属性,所以我想出了一个解决方案,你只需要向控制器添加一个属性。 There are two steps:有两个步骤:

Add DisplayNameAttribute on the controller:在控制器上添加DisplayNameAttribute

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

Then in the Swagger configuration, you can override the base functionality using the GroupActionsBy function to pull the name that you specified in that attribute:然后在 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() is an extension method defined in the Swagger-Net library. ControllerName()Swagger-Net库中定义的扩展方法。 If you aren't using that you can also get the controller name from apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName如果您不使用它,您还可以从apiDesc.ActionDescriptor.ControllerDescriptor.ControllerName获取控制器名称

Version 5 of Swashbuckle supports the following option (to be used in the call to AddSwaggerGen() ): Swashbuckle 的第 5 版支持以下选项(用于调用AddSwaggerGen() ):

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

This should be used in combination with the following attribute on your controllers or actions:这应该与控制器或操作上的以下属性结合使用:

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

However, by default the group name is used to include the operation in a specific document.但是,默认情况下,组名用于将操作包含在特定文档中。 So this may lead to unexpected results (depends on your naming of the document in calls to options.SwaggerDoc(name, ...) ).因此,这可能会导致意外结果(取决于您在调用options.SwaggerDoc(name, ...)对文档的命名)。

To make it work you may have to add this:要使其工作,您可能必须添加以下内容:

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

Here, for every operation, name is the name of a document and the group name is available in api.GroupName .在这里,对于每个操作, name 是文档的名称,组名在api.GroupName可用。 To include the operation in the document regardless of its group name, simply return true.要将操作包含在文档中而不考虑其组名称,只需返回 true。

By default if I have a controller called ShippingController then the swagger generated UI with name "Shipping"默认情况下,如果我有一个名为 ShippingController 的控制器,那么 swagger 生成的 UI 名称为“Shipping”

I was looking to change the name of my controller to something more friendly or in another language.我希望将控制器的名称更改为更友好的名称或使用另一种语言。 The best I could find was to use a SwaggerOperation attribute to change the name, but this has the limitation that it is a method level attribute and I dont really want to specify the name on every method.我能找到的最好的方法是使用 SwaggerOperation 属性来更改名称,但这有一个限制,即它是一个方法级别的属性,我真的不想在每个方法上指定名称。

So, I created a convention class to use with controller Route attribute, that we usually use on our controllers and then have the swagger use that to be the name of the controller.所以,我创建了一个约定类来与控制器 Route 属性一起使用,我们通常在我们的控制器上使用它,然后让 swagger 使用它作为控制器的名称。 Well you know there is a name property on the attribute but the generated swagger doesnt seem to use it.好吧,您知道属性上有一个 name 属性,但生成的 swagger 似乎没有使用它。

STEP 1: Create this class:第 1 步:创建这个类:

When the app starts up it will run this and I will be able to look up the Route attribute on my controllers if they have the attribute specified and then use the name property to change the name of the Controller.当应用程序启动时,它将运行它,如果我的控制器指定了该属性,我将能够在我的控制器上查找 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;
                }
            }

        }
    }
}

STEP 2: Startup.cs:第 2 步:Startup.cs:

Modify the StartUp.cs file and in the configure services we need to register our class in the Conventions list.修改 StartUp.cs 文件,在配置服务中,我们需要在约定列表中注册我们的类。 See below:见下文:

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

STEP 3: In each controller add name property in Route Attribute:第 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

Now when I run the app and my swagger is generated you can see the controller name is changed to be the same as the text in the route attributes name property.现在,当我运行应用程序并生成我的 swagger 时,您可以看到控制器名称已更改为与路由属性名称属性中的文本相同。

在此处输入图片说明

If one wants to do this at a Controller / Class level , the following is a very useful extract from here如果想在控制器/类级别执行此操作,以下是此处的非常有用的摘录

use the [ApiExplorerSettings(GroupName = "Group")] on your controllers在控制器上使用 [ApiExplorerSettings(GroupName = "Group")]

Then in Startup然后在启动

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

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

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

Also note that还要注意的是

5.0.0-beta of swashbuckle now includes an TagActionsBy overload that supports returning an array of tags. swashbuckle 的 5.0.0-beta 现在包含支持返回标签数组的 TagActionsBy 重载。 This should allow for the above customizations to be simplified这应该允许简化上述自定义

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

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