[英]Is there a way change the Controller's name in the swagger-ui page?
从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
操作放在Test
和Release1
组中。
我尝试使用 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.