Refit API Client:单对象中能否混合定义Body与Query参数
Refit单请求对象混合配置Query、路由、Body参数说明
完全支持这种写法,你不需要把不同来源的API参数拆成多个独立的方法入参,Refit原生支持通过特性标记单个复杂模型类里不同属性的参数来源,只需要修正几个写法细节就能正常对接你的ASP.NET接口。
核心配置规则
- 路由参数:不需要额外加特性,只要属性名和接口路径模板里的占位符名称一致,Refit会自动从请求对象里取值替换路由段。
- Query查询参数:给对应属性加
[Query]特性即可,发起请求时属性值会被自动拼接到URL的查询串中,支持自定义参数别名。 - Body请求体参数:给对应属性加
[Body]特性即可,注意同一个请求模型类里只能有一个属性标记[Body],否则会触发运行时错误,默认会将属性值序列化为JSON格式作为请求体,正好匹配ASP.NET Core[FromBody]的默认接收格式。
修正后的可运行代码示例
ASP.NET 接口端
你原有接口逻辑无需调整即可对接:
[Route("documents/{id}")] [HttpPost] public void PostDocument(int id, [FromBody] Document document) { // 业务逻辑 }
Refit客户端定义
注意路径占位符直接写属性名id即可,不需要加对象前缀,你原来写的{document.id}是错误写法,会导致路由参数匹配失败:
public interface IDocumentApi { [Post("/documents/{id}")] Task PostDocument(PostDocumentRequest request); }
请求模型类
你的原有模型思路完全正确,仅需注意路由参数属性无需额外标记:
public class PostDocumentRequest { // 自动匹配路由段{id},无需加特性 public int Id { get; set; } // 标记为Query参数,会自动拼接为?LocalDateTime=xxx的格式 [Query] public DateTime? LocalDateTime { get; set; } // 标记为请求体,序列化为JSON传递,一个类仅允许一个[Body]属性 [Body] public Document Document { get; set; } }
实际请求效果
当你给PostDocumentRequest赋值Id=1001、LocalDateTime=2024-05-20 14:30:00、Document为对应文档对象时,Refit生成的HTTP请求完全符合ASP.NET接口的要求:
- 请求路径:
/documents/1001?LocalDateTime=2024-05-20T14%3A30%3A00 - 请求头:
Content-Type: application/json - 请求体:
Document对象序列化后的JSON字符串
内容的提问来源于stack exchange,提问作者Grant Trevor
相关产品推荐
相关产品推荐

