My situation is rather simple. I have a very large .NET Core 2.1 MVC/WebApi divided into several Areas, representing different modules of my system. I use Swagger (SwashBuckle) and it works very well. My routing are like {area}/{controller}/{action}
.
In Swagger UI, every action is grouped into the controllers (standard behaviour). My list of controllers and operations is becoming very very large and hard to grasp. Because of that, i would love if Swagger could divide my controllers into the different areas! Making it possible to collapse area x
and every controller within area x
.
I really miss this feature or a way to implement it myself! Any ideas are appreciated!
UPDATE
I've tried annotating actions with tags.
This gives me:
- Area 1
- MethodFromControllerA()
- MethodFromControllerB()
- Area 2
- MethodFromControllerC()
- MethodFromControllerD()
What i want:
- Area 1
- ControllerA
- MethodFromControllerA()
- ControllerB
- MethodFromControllerB()
- Area 2
- ControllerC
- MethodFromControllerC()
- ControllerD
- MethodFromControllerD()
Update 2
Another option would be to have several specifications for each of my areas. Like different Swagger UIs for every area. Possible?
You first need to install annotations and enable them in your startup:
services.AddSwaggerGen(c =>
{
c.EnableAnnotations();
});
Then you need to add your "area" as tag to every action.
[SwaggerOperation(
Tags = new[] { "Area51" }
)]
When you open your swagger ui, it should be automatically grouped by tag now (per default the controller name is the chosen tag).
Further nested grouping of endpoints is currently not possible out of the box with the existing swagger ui generator.
If your still looking to do this by area name, this is the complete code for doing it in Swashbuckle.AspNetCore:
c.OperationFilter<TagByAreaNameOperationFilter>();
public class TagByAreaNameOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
var areaName = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(typeof(AreaAttribute), true)
.Cast<AreaAttribute>().FirstOrDefault();
if (areaName != null)
{
operation.Tags = new List<OpenApiTag> { new OpenApiTag { Name = areaName.RouteValue } };
}
else
{
operation.Tags = new List<OpenApiTag> { new OpenApiTag { Name = controllerActionDescriptor.ControllerName } };
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With