Refit代理与DelegatingHandler间除Header外有哪些可行传值方案
可行实现方案
方案1:使用Refit原生[Property]特性传递上下文参数(最推荐)
Refit 原生提供了[Property]特性,专门用于向请求上下文传递参数,不会将参数带入最终发出的HTTP请求头/请求体中,完全适配通用Handler的需求。
接口改造
将原Header参数替换为[Property]标记的参数:
Task<Response> UserInfo(string id, [Property("identity")] string identity);
简化调用(可选,解决重复传参问题)
给Refit接口写扩展方法,内部自动补全参数:
public static class YourApiExtensions { public static Task<Response> UserInfo(this IYourApi api, string id) { return api.UserInfo(id, id); } }
改造后调用只需要传一次参数:api.UserInfo("234")
Handler逻辑改造
直接从HttpRequestMessage的Options(.NET Core 3.0+)或Properties(兼容老版本)中读取参数,不需要处理Header移除逻辑:
// 优先读取新版本Options if (request.Options.TryGetValue(new HttpRequestOptionsKey<string>("identity"), out var identity) && !string.IsNullOrEmpty(identity)) { return GenerateToken(identity); } // 兼容.NET Framework/旧版本.NET的Properties if (request.Properties.TryGetValue("identity", out var identityObj) && identityObj is string oldIdentity && !string.IsNullOrEmpty(oldIdentity)) { return GenerateToken(oldIdentity); }
优势
- 参数完全不进入实际HTTP请求链路,无需手动清理Header
- 符合Refit的设计规范,没有额外依赖
- 通用Handler不需要感知业务参数的位置,适配所有接口
方案2:封装服务层屏蔽重复传参逻辑(改动最小)
如果不想改动现有Handler的Header处理逻辑,只需要在Refit接口之上封装一层业务服务类,对上层调用隐藏重复传参的细节:
封装示例
public class UserApiService { private readonly IYourApi _refitApi; public UserApiService(IYourApi refitApi) { _refitApi = refitApi; } // 对外暴露的方法只需要传一个id public Task<Response> UserInfo(string id) { // 内部自动填充Header参数 return _refitApi.UserInfo(id, id); } }
优势
- 完全不需要改动现有Handler和Refit接口的定义
- 上层业务代码无感知,适配性强
方案3:使用作用域注入传递Identity(适合固定上下文场景)
如果你的Identity是当前请求上下文固定的参数(比如服务端调用时的当前登录用户ID),可以通过依赖注入的作用域传递,不需要在接口参数中声明:
- 注册作用域服务存储Identity:
services.AddScoped<IdentityContext>() - 请求进入时给
IdentityContext赋值 - 自定义Handler中注入
IdentityContext直接读取Identity值
优势
- 接口定义完全不需要额外参数,调用零感知
- 适合Identity来自请求上下文的场景,通用性更强
内容的提问来源于stack exchange,提问作者codebased
相关产品推荐
相关产品推荐

