Swagger UI 发送绑定到单个操作参数的多个 headers 作为单个 json object,而不是多个 headers
Swagger UI sends multiple headers bound to a single action parameter as a single json object, rather than as multiple headers
我按照通常的 MS 文档在 asp.net 核心 3.1 API 中启用了 Swagger。
https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-3.1&tabs=visual-studio
它工作正常。
以下控制器在 Postman 中运行良好。
myBody 的 Body1 和 Body2 字段绑定自 POST 请求的 json body。
myHeader 从请求的两个“Header1”和“Header2”headers.
namespace MyApi.Controllers
{
[ApiController]
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult Post(
[FromHeader] MyHeaders myHeaders,
MyBody myBody)
{
return Ok();
}
}
public class MyHeaders
{
[FromHeader]
public string Header1 { get; set; }
[FromHeader]
public string Header2 { get; set; }
}
public class MyBody
{
public string Body1 { get; set; }
public string Body2 { get; set; }
}
}
但是 Swagger UI 只为两个 header 传递 1 json object:
[招摇ui][1]
并生成对应的curl命令:
curl -X POST "https://localhost:5001/test" -H "accept: */*" -H "myHeaders: header1,string,header2,string" -H "Content-Type: application/json" -d "{\"body1\":\"string\",\"body2\":\"string\"}"
问题出在 -H "myHeaders: header1,string,header2,string" 部分。正如预期的那样,模型绑定将 myHeaders.Header1 和 .Header2 设置为 null,因为 header 被命名为“myHeaders”。
用 **-H "Header1: cat" -H "Header2: dog" 替换部分可以正常工作。
Asp.net 足够聪明,可以通过匹配名称将单独的 header 映射到单个操作参数。但是我怎样才能让 Swagger 有多个 headers UI,所以它的 curl 命令有效?
我知道我可以用 [FromHeader] string Header1, [FromHeader] string Header2
替换 [FromHeader] MyHeaders myHeaders
,但我想避免这种情况。将有几十个动作都收到同一组 headers。
Yura 在 How to use [FromHeader] attribute with custom model binding in Asp.Net Core 2.2 中的回答给出了解决方案
就是把[FromHeader] MyHeaders myHeaders改成[FromQuery] MyHeaders myHeaders。
这使 Swagger UI 工作,即使 FromQuery 似乎与 Header1 和 Header2 上的 FromHeader 属性相矛盾。
固定码为:
public class TestController : ControllerBase
{
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult Post(
[FromQuery] MyHeaders myHeaders, // FromHeader is changed to FromQuery
MyBody myBody)
{
return Ok();
}
}
public class MyHeaders // unchanged
{
[FromHeader]
public string Header1 { get; set; }
[FromHeader]
public string Header2 { get; set; }
}
我按照通常的 MS 文档在 asp.net 核心 3.1 API 中启用了 Swagger。 https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-3.1&tabs=visual-studio 它工作正常。
以下控制器在 Postman 中运行良好。 myBody 的 Body1 和 Body2 字段绑定自 POST 请求的 json body。 myHeader 从请求的两个“Header1”和“Header2”headers.
namespace MyApi.Controllers
{
[ApiController]
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult Post(
[FromHeader] MyHeaders myHeaders,
MyBody myBody)
{
return Ok();
}
}
public class MyHeaders
{
[FromHeader]
public string Header1 { get; set; }
[FromHeader]
public string Header2 { get; set; }
}
public class MyBody
{
public string Body1 { get; set; }
public string Body2 { get; set; }
}
}
但是 Swagger UI 只为两个 header 传递 1 json object: [招摇ui][1]
并生成对应的curl命令:
curl -X POST "https://localhost:5001/test" -H "accept: */*" -H "myHeaders: header1,string,header2,string" -H "Content-Type: application/json" -d "{\"body1\":\"string\",\"body2\":\"string\"}"
问题出在 -H "myHeaders: header1,string,header2,string" 部分。正如预期的那样,模型绑定将 myHeaders.Header1 和 .Header2 设置为 null,因为 header 被命名为“myHeaders”。 用 **-H "Header1: cat" -H "Header2: dog" 替换部分可以正常工作。
Asp.net 足够聪明,可以通过匹配名称将单独的 header 映射到单个操作参数。但是我怎样才能让 Swagger 有多个 headers UI,所以它的 curl 命令有效?
我知道我可以用 [FromHeader] string Header1, [FromHeader] string Header2
替换 [FromHeader] MyHeaders myHeaders
,但我想避免这种情况。将有几十个动作都收到同一组 headers。
Yura 在 How to use [FromHeader] attribute with custom model binding in Asp.Net Core 2.2 中的回答给出了解决方案 就是把[FromHeader] MyHeaders myHeaders改成[FromQuery] MyHeaders myHeaders。 这使 Swagger UI 工作,即使 FromQuery 似乎与 Header1 和 Header2 上的 FromHeader 属性相矛盾。
固定码为:
public class TestController : ControllerBase
{
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult Post(
[FromQuery] MyHeaders myHeaders, // FromHeader is changed to FromQuery
MyBody myBody)
{
return Ok();
}
}
public class MyHeaders // unchanged
{
[FromHeader]
public string Header1 { get; set; }
[FromHeader]
public string Header2 { get; set; }
}