AspNetCoreOpenApiDocumentGenerator incorrectly generates query params with special path param names
#2915 opened on Jun 19, 2020
Description
Hi,
I am trying to generate a controller in my project from the swagger files in the Grafeas project. Specifically, I am experimenting with this file: https://github.com/grafeas/grafeas/blob/master/proto/v1beta1/swagger/project.swagger.json#L85
Note the highlighted line. The path parameter is {name=projects/*}. I am actually not sure what this template format means, as I wasn't able to find this format in the OpenAPI spec.
So I use this file to generate a controller, like so:
dotnet-nswag.exe openapi2cscontroller /input:project.swagger.json /classname:Test /output:TestController.cs /namespace:Test /UseActionResultType:true /ControllerStyle:Abstract /ControllerBaseClass:Microsoft.AspNetCore.Mvc.ControllerBase
This generates the following code (not the full class, just the relevant code snippet):
/// <summary>Gets the specified project.</summary>
/// <param name="name">The name of the project in the form of `projects/{PROJECT_ID}`.</param>
/// <returns>A successful response.</returns>
[Microsoft.AspNetCore.Mvc.HttpGet, Microsoft.AspNetCore.Mvc.Route("v1beta1/{name=projects/*}")]
public abstract System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.ActionResult<ProjectProject>> GetProject(string name);
And then I build an AspNetcore service that uses this controller. I also want NSwag to generate a Swagger, so I do (in ConfigureServices):
services.AddSwaggerDocument(x => { x.Title = Program.ApplicationName; });
And then in Configure:
app.UseOpenApi();
app.UseSwaggerUi3(x => x.DocumentTitle = $"{Program.ApplicationName} Swagger");
This will produce a Swagger page that marks the name parameter as a query param, even though it's defined in the source file that it should be a path param. The actual service works fine, so I can trigger the endpoint via v1beta1\<name>, so the problem seems to be with only the Swagger generation.
If I manually change the path parameter in the generated controller route from "v1beta1/{name=projects/*}" to "v1beta1/{name}", then the Swagger page is correctly generated. I suspect NSwag somewhere picks up the equals sign and assumes that it's a query param.
Unfortunately, I am consuming the original swagger definitions from a 3rd party project (Grafeas), so changing them is not an option.
I can work around this by applying the [Route("v1beta1/{name")] attribute on my derived class from the abstract controller, but I would prefer not to duplicate these routes on every method I am implementing.
There is another file in the API spec, which has a lot more methods and Swagger generation actually breaks with that file, because there are multiple endpoints with the same route (since they are generated with a query param).
I have tested this on https://generator.swagger.io/, and by putting in the raw file there, it generates the correct Swagger page, so I would assume that the original json file is correct.
Thanks for looking into this, Balazs