In the following image you can see two of my controllers shown in the swagger-ui page. 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?
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.

Thanks very much
[ApiExplorerSettings(GroupName = @"Learner")]
public class ManagementDashboardWidgetController : Controller
{
...
}
Unfortunately when I use [ApiExplorerSettings(GroupName = @"Learner")] on a controller (or action) I get a 'type of namespace GroupName could not be found error'. Looking at the definition of the ApiExplorerSettings object only shows IgnoreApi as a possible setting.
Mhh my bad. I forgot that there are still people not using ASP.NET Core yet :P
It's been long time since I've used ApiExplorer before ASP.NET Core, but I remeber that there was an attribute one puts on the header to make it work that worked with ApiExplorer and iirc Swashbuckle uses the ApiExplorer Api to get the data it needs for generating the schema.
@XELANAMYT Did you end up finding what it was? I am also looking to change default controller name...
is maybe a hack but I make it work using a IDocumentFilter.
then in Apply() method take the swaggerDoc param and for each item navigate to property "Value.get.tags"; here you have the name of Controller where method belongs to, change it in all items matching the same tag value.
@fenix2222 I did manage to get it working. I added the following attribute to each action in the controller:
[SwaggerOperation(Tags = new[] { "Management Reports" })]
Not exactly ideal as you have to decorate all the actions otherwise the undecorated ones will show up with the controller name, still it works!
Have you looked at the config setting GroupActionsBy described in readme. I think that's what you want.
This allows you to provide a custom strategy for the Operation tag, which is used to group operations and it gets applied across the board - no annotations required
I don't understand why this is not working.
I have custom attribute on each controller and trying to rename controller using IOperationFilter, like:
public class CustomControllerName: IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (apiDescription.GetControllerAndActionAttributes<ApiControllerAttribute>().Any())
{
apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName = apiDescription.GetControllerAndActionAttributes<ApiControllerAttribute>().ToList()[0].Name;
}
}
}
After the first request, the result is very strange, the first operation takes default controller name every other grouped with changed name. Like I have ProjectController class and would like to change the name to Projects so the result is like:
operation 1
Projects
operation 2
operation 3
After second request everything becomes good
operation 1
operation 2
operation 3
Any ideas?
not sure if this helps, but we use an attribute on each controller class as well as the 'GroupActionsBy' that DDD referred to.
swaggerDocsConfig.GroupActionsBy(ExtractControllerGroupingValue);
and this is the static function to look for the string to use
private static string ExtractControllerGroupingValue(ApiDescription apiDescription)
{
// see if we have an attribute to provide our name
var controllerGroupName = apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<GroupByNameAttribute>().FirstOrDefault();
// revert to the old logic if needed
return controllerGroupName != null ? controllerGroupName.Name : apiDescription.ActionDescriptor.ControllerDescriptor.ControllerName;
}
@paul3291 Yes, that works. But I'm interesting to do the same in IOperationFilter, I have some other logic there and want to have all the logic in one place
@Jcomper - an operation filter is a hook into the Swagger generation process. This process converts an ApiDescription (metadata exposed by WebApi) to a Swagger Operation.
So, the goal of a filter implementation is to modify the "operation" parameter not the "apiDescrition". Specifically in your case, you need to set it's "Tags" Property
@paul3291 I was just trying to implement your code, and it seems like ControllerDescriptor is no longer available in 2.0? I've tried a few ways to figure this out, but to no avail. Do you by any chance have updated code for this method? Thanks!
Hi @chrispaynter, sorry we haven't swapped to .Net Core 2.0 yet, you probably be best to take a look over at https://github.com/domaindrivendev/Swashbuckle.AspNetCore and see what options are available now.
Oh right! I hadn't realised I was on the wrong issues page! Thanks @paul3291.
@TsengSR I added this ApiExplorerSettings(GroupName = @"GroupName") and my controller disappeared from the docs. Am i missing something?
@TsengSR I added this ApiExplorerSettings(GroupName = @"GroupName") and my controller disappeared from the docs. Am i missing something?
Me too!
@vinguan I've confirmed this behavior as well. @TsengSR Is this really expected behaviour ?
@vinguan, @casertano, @alexmarshall132 Yes, by default swagger will include in the swagger doc the actions that don't have a GroupName set or the actions which have the GroupName matching the swagger doc name. This way you could separate your api actions into different docs/versions.
If you don't want this behaviour, you need to specify a different DocInclusionPredicate. Something like this:
services.AddSwaggerGen(options =>
{
options.SwaggerDoc(version,
new Info
{
Title = name,
Version = version
});
options.DocInclusionPredicate((_, api) => !string.IsNullOrWhiteSpace(api.GroupName));
options.TagActionsBy(api => api.GroupName);
});
Most helpful comment
@vinguan, @casertano, @alexmarshall132 Yes, by default swagger will include in the swagger doc the actions that don't have a GroupName set or the actions which have the GroupName matching the swagger doc name. This way you could separate your api actions into different docs/versions.
If you don't want this behaviour, you need to specify a different DocInclusionPredicate. Something like this: