Swagger UI 尝试操作方法不替换路由参数,而是发送占位符“{paramName}”
Swagger UI try action method does not replace route parameters, it sends the placeholder "{paramName}" instead
使用 ASP.Net Core 3.1 和 NSwag.AspNetCore 来自 NuGet 的 v13.7.0
我有这个动作方法
[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
}
}
而 GetPersonInput 是:
public class GetPersonInput
{
[FromQuery]
public IdentityType? IdentityType { get; set; }
[FromRoute]
public string IdentityNumber { get; set; }
}
当我从 Postman 调用它时,它工作正常。但是当我从 Swagger UI 调用它时,它很好地识别了方法签名,它将 /{IdentityNumber}
传递给 URI 而不是我在 UI:
中输入的数字
实际调用是(来自Postman):
https://localhost:44343/api/person/25062140?identityType=DU
但是 swagger UI 构建了这个卷曲:
curl -X GET "https://localhost:44343/api/person/{identityNumber}?identityType=DU" -H "accept: application/json"
产生此请求:
https://localhost:44343/api/person/{identityNumber}?identityType=DU
导致异常:
System.FormatException: Input string was not in a correct format.
这是我的启动配置
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();
});
}
其实很简单,路由参数是区分大小写的。只需将 {identityNumber}
更改为 {IdentityNumber}
:
[HttpGet("{IdentityNumber}", Name = nameof(GetPersonById))]
[ApiConventionMethod(typeof(DefaultApiConventions), nameof(DefaultApiConventions.Get))]
public ActionResult<PersonResource> GetPersonById([FromQuery] GetPersonInput input)
{
//code omitted for brevity
}
使用 ASP.Net Core 3.1 和 NSwag.AspNetCore 来自 NuGet 的 v13.7.0
我有这个动作方法
[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
}
}
而 GetPersonInput 是:
public class GetPersonInput
{
[FromQuery]
public IdentityType? IdentityType { get; set; }
[FromRoute]
public string IdentityNumber { get; set; }
}
当我从 Postman 调用它时,它工作正常。但是当我从 Swagger UI 调用它时,它很好地识别了方法签名,它将 /{IdentityNumber}
传递给 URI 而不是我在 UI:
实际调用是(来自Postman): https://localhost:44343/api/person/25062140?identityType=DU
但是 swagger UI 构建了这个卷曲:
curl -X GET "https://localhost:44343/api/person/{identityNumber}?identityType=DU" -H "accept: application/json"
产生此请求:
https://localhost:44343/api/person/{identityNumber}?identityType=DU
导致异常:
System.FormatException: Input string was not in a correct format.
这是我的启动配置
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();
});
}
其实很简单,路由参数是区分大小写的。只需将 {identityNumber}
更改为 {IdentityNumber}
:
[HttpGet("{IdentityNumber}", Name = nameof(GetPersonById))]
[ApiConventionMethod(typeof(DefaultApiConventions), nameof(DefaultApiConventions.Get))]
public ActionResult<PersonResource> GetPersonById([FromQuery] GetPersonInput input)
{
//code omitted for brevity
}