是否可以拥有一种将FromHeader、FromRoute、FromQuery和 FromBody组合在一起的复杂请求类型?

后端开发 2026-07-10

正如标题所示,我正在尝试创建这样的DTO对象:

public class RequestDto
{
    [FromHeader]
    public string correlationId;

    [FromRoute]
    public string Id { get; set; }

    [FromQuery]
    public string Status { get; set; }
}

当我按如下方式使用它时:

[HttpGet("{id}/enrollments")]
public async Task<IActionResult> GetEnrollments(RequestDto request){...}

并尝试通过Swagger填充来测试端点时,curl仍然会生成为:

curl -X 'GET' \
  'http://localhost:8080/{id}/entrollments?Status=Enrolled' \
-H 'accept: text/plain'
-H 'x-correlation-id: 12343'

响应

{
    "errors":{
        "id":"{id}",
        "message":"id not found"
    }
}

字面量字符串 "{id}" 正在Id字段中被填充。并且通过insomnia或 Postman发送请求,或使用类似curl的方式时,它可以正常工作:

curl -X 'GET' \
  'http://localhost:8080/1234/enrollments?Status=Enrolled' \
-H 'accept: text/plain'

响应

{
    "id":"1234"
    "entrollments":[
        "TEST-1"
    ]
}

为什么Swagger UI一直生成错误的URL?

即使每个绑定属性只使用一次,是否仍不推荐在一个通用的复杂类中使用多个绑定属性?

当请求DTO拥有多个源绑定时,行为上是否存在不一致?

解决方案

是的,这正是那种看起来应该能工作,但实际应用中并不顺畅的情况。

Technically, ASP.NET Core allows multiple binding sources, but when you put [FromRoute], [FromQuery], and [FromHeader] inside a single DTO, Swagger/OpenAPI gets confused. It can’t properly map where each value should come from, so it ends up generating wrong URLs (like keeping {id} instead of replacing it).

这就是为什么在Postman或 curl中工作得很好——你是手动传递所有内容——但Swagger依赖元数据,在这里就显得吃力。

更简单、也更可靠的方式,是在控制器中把它们分开处理:

public async Task<IActionResult> GetEnrollments(
    [FromRoute] string id,
    [FromQuery] string status,
    [FromHeader(Name = "correlation-id")] string correlationId)

在一个DTO中混合多源是可能的,但并不值得去麻烦,尤其是在你使用Swagger的情况下。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章