Refit中混合请求体、查询参数与动态头部字段的实现问询
Refit 混合请求体/查询参数/请求头的实现方案
Refit原生不支持在单个复杂类型参数的属性上混合使用请求体、[Query]和[Header]特性——默认情况下,单个复杂类型会被整体序列化为请求体,类属性上的[Query]、[Header]标记不会被自动识别处理。
扩展实现:自定义参数绑定器
通过实现Refit的IParameterBinder接口,可以自定义参数的绑定逻辑,将单个类的不同属性分别映射到请求体、查询参数和请求头:
1. 实现自定义参数绑定器
using System.Text; using System.Text.Json; using System.Web; using Refit; using System.Net.Http; using System.Reflection; public class CreateStepContextBinder : IParameterBinder { public async Task BindAsync(HttpRequestMessage request, ParameterInfo parameterInfo, object? argument, CancellationToken cancellationToken) { if (argument is not CreateStepContext context) return; // 处理请求体:序列化Id属性 var requestBody = new { context.Id }; var jsonContent = JsonSerializer.Serialize(requestBody); request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); // 处理查询参数:添加StepType(非空时) if (!string.IsNullOrWhiteSpace(context.StepType)) { var uriBuilder = new UriBuilder(request.RequestUri!); var queryParams = HttpUtility.ParseQueryString(uriBuilder.Query); queryParams["StepType"] = context.StepType; uriBuilder.Query = queryParams.ToString(); request.RequestUri = uriBuilder.Uri; } // 处理请求头:添加X-Client-ID request.Headers.Add("X-Client-ID", context.ClientId); } }
2. 在接口方法中指定绑定器
修改Refit接口的方法参数,通过[ParameterBinder]标记指定自定义绑定器:
[Post("/api/v2/steps")] Task CreateStep([ParameterBinder(typeof(CreateStepContextBinder))] CreateStepContext request);
备选方案:参数拆分+封装调用
如果不想自定义绑定器,也可以拆分接口参数,同时用CreateStepContext封装参数后调用:
// 定义拆分参数的接口 [Post("/api/v2/steps")] Task CreateStep([Body] CreateStepBody body, [Query] string? stepType, [Header("X-Client-ID")] string clientId); // 配套的请求体类 public class CreateStepBody { public int Id { get; set; } } // 调用时从CreateStepContext拆包 var context = new CreateStepContext { Id = 1, StepType = "Test", ClientId = "Client123" }; await api.CreateStep(new CreateStepBody { Id = context.Id }, context.StepType, context.ClientId);
内容的提问来源于stack exchange,提问作者Siavash Mortazavi
相关产品推荐
相关产品推荐

