Swagger UI try action method does not replace route parameters, it sends the placeholder "{paramName}" instead
Using ASP.Net Core 3.1 with NSwag.AspNetCore v13.7.0 from NuGet
I have this action method
[ApiController]
[ApiVersion(EosApiVersion.CurrentVersion)]
[Route(EosApiConsts.BaseRoute + "/[Controller]")]
public class PartyController : ControllerBase
{
[HttpGet("{identityNumber}", Name = nameof(GetPersonById))]
[ApiConventionMethod(typeof(DefaultApiConventions), nameof(DefaultApiConventions.Get))]
public ActionResult<PersonResource> GetPersonById([FromQuery] GetPersonInput input)
{
//code omitted for brevity
}
}
And GetPersonInput is:
public class GetPersonInput
{
[FromQuery]
public IdentityType? IdentityType { get; set; }
[FromRoute]
public string IdentityNumber { get; set; }
}
When I invoke it from Postman it works fine. But when I invoke it from Swagger UI, who identify the method signature well, it passes /{IdentityNumber}
to the URI instead of the number I entered in the UI:
The actual call is (from Postman): https://localhost:44343/api/person/25062140?identityType=DU
but swagger UI builds this curl:
curl -X GET "https://localhost:44343/api/person/{identityNumber}?identityType=DU" -H "accept: application/json"
which produces this request:
https://localhost:44343/api/person/{identityNumber}?identityType=DU
which lead to an exception:
System.FormatException: Input string was not in a correct format.
Here is my Startup configuration
public void ConfigureServices(IServiceCollection services)
{
//Add routing
services.AddRouting(options =>
{
options.LowercaseUrls = true;
});
services.AddControllers();
//services.AddControllers().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //The problem also happens with CompatiblityVersion set to 2.2
//Add OpenApi
services.AddOpenApiDocument();
services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new ApiVersion(1, 0, status: "dev");
options.ApiVersionReader = new QueryStringApiVersionReader();
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
//Use OpenApi with UIs
app.UseOpenApi();
app.UseSwaggerUi3();
//app.UseReDoc();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Actually it's very simple, the route parameter is case senstive. Just change {identityNumber}
to {IdentityNumber}
:
[HttpGet("{IdentityNumber}", Name = nameof(GetPersonById))]
[ApiConventionMethod(typeof(DefaultApiConventions), nameof(DefaultApiConventions.Get))]
public ActionResult<PersonResource> GetPersonById([FromQuery] GetPersonInput input)
{
//code omitted for brevity
}