'ASP.NET - Swagger duplicates path and query parameters
I have two endpoints on my controller with the same parameters, which should automatically come from the path.
This one works fine in Swagger, both parameters are required and coming from the path.
[HttpGet("{id}/workflows/{wfId}/signedCosrFile")]
public async Task<ActionResult> DownloadSignedCosrFile(int id, int wfId)
Url is fine, both parameters are coming from path: Cosrs/1/workflows/1/signedCosrFile
Works fine is Swagger too:
This one has the same signature and should work as the one above:
[HttpGet("{id}/workflows/{wfId}/generatedCosrFile")]
public async Task<ActionResult> DownloadGeneratedCosrFile(int id, int wfId)
Url is wrong, parameters are already coming from path, should not come from the query as well: Cosrs/1/workflows/1/generatedCosrFile?id=1&wfId=1
Also in Swagger it shows as duplicated, coming from the path and query too:
Solution 1:[1]
It is worth noting that, normally, if the parameter has the same name in the path and as a variable it should not appear in double. So you have some bug somewhere I guess. If you want to work around it, keep reading to the end, my methodology can help you too.
But I would also like to add that if, like me, you like to have your C# variables in camelCase but your path parameters in snake_case, this is also going to be a problem. SwashBuckle will display both, the one from the path (in HttpGet("") and such) as path parameter, and the one in the arguments of the function as a query parameter.
To avoid this, I use a function to transform a string with CamelCase to snake_case (made into an extension method because why not) :
public static string ToSnakeCase(this string value)
{
if (value.Length < 2) return value;
var sb = new StringBuilder();
sb.Append(char.ToLowerInvariant(value[0]));
for (int i = 1; i < value.Length; i++)
{
char c = value[i];
if (char.IsUpper(c))
sb.Append('_');
sb.Append(char.ToLowerInvariant(c));
}
return sb.ToString();
}
Then create a filter to find out if I have some query parameters that are just the same as a path parameter but in snake case. If it is so, then I remove the query ones, since they are the duplicates :
public class DuplicatePathParamsOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
return;
var queryParameters = operation.Parameters.Where(p => p.In == ParameterLocation.Query && !string.IsNullOrEmpty(p.Name)).ToList();
var pathParameters = operation.Parameters.Where(p => p.In == ParameterLocation.Path && !string.IsNullOrEmpty(p.Name)).ToList();
foreach (var parameter in queryParameters)
{
var snake = parameter.Name.ToSnakeCase();
if (pathParameters.Any(p => p.Name == snake))
operation.Parameters.Remove(parameter);
}
}
}
And finally add it to the options of the SwaggerGen :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwaggerGen(options =>
options.OperationFilter<DuplicatePathParamsOperationFilter>();
);
If your bug persists, you could easily edit the filtering method so that it also checks for query params and path params with the same name. You can just replace if (pathParameters.Any(p => p.Name == snake)) with if (pathParameters.Any(p => p.Name == snake || p.Name == parameter.Name))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mickael V. |


