如何在.NET 6中获取Refit客户端当前请求的响应类型?
在Refit的DelegatingHandler中获取响应类型
要在RequestPropertyHandler里拿到目标响应类型(比如示例中的GetUsersResponse),可以通过Refit存入HttpRequestMessage.Properties的方法元信息来解析,具体实现步骤如下:
从请求属性中获取当前调用的接口方法信息
Refit会把接口的MethodInfo存入HttpMessageRequestOptions.MethodInfo键下,直接取出即可。逐层拆解返回值的泛型嵌套类型
你的接口方法返回Task<ApiResponseMessage<GetUsersResponse>>,需要拆两层泛型参数:
- 先提取
Task<T>中的T,即ApiResponseMessage<GetUsersResponse> - 再提取
ApiResponseMessage<T>中的T,就是最终的GetUsersResponse
修改后的Handler代码
class RequestPropertyHandler : DelegatingHandler { public RequestPropertyHandler(HttpMessageHandler innerHandler = null) : base(innerHandler ?? new HttpClientHandler()) {} protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // 获取当前调用的接口方法信息 if (request.Properties.TryGetValue(HttpMessageRequestOptions.MethodInfo, out var methodObj) && methodObj is MethodInfo methodInfo) { // 解析Task的泛型参数:Task<ApiResponseMessage<GetUsersResponse>> -> ApiResponseMessage<GetUsersResponse> var wrappedResponseType = methodInfo.ReturnType.GetGenericArguments()[0]; // 解析ApiResponseMessage的泛型参数:ApiResponseMessage<GetUsersResponse> -> GetUsersResponse if (wrappedResponseType.IsGenericType && wrappedResponseType.GetGenericTypeDefinition() == typeof(ApiResponseMessage<>)) { var targetResponseType = wrappedResponseType.GetGenericArguments()[0]; // 此处已拿到目标响应类型,可按需使用 Console.WriteLine($"当前请求的响应类型:{targetResponseType.Name}"); } } // 保留原有路径修改逻辑 var builder = new UriBuilder(request.RequestUri); if (request.Properties.TryGetValue(HttpMessageRequestOptions.InterfaceType, out var interfaceObj) && interfaceObj is Type interfaceType) { builder.Path = $"/{interfaceType.Name}{builder.Path}"; request.RequestUri = builder.Uri; } return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } }
关键说明
- 如果你的接口存在不同返回格式(比如部分方法直接返回
Task<T>无包装),需要增加分支判断适配不同场景。 - 代码中增加了空值判断,避免因属性不存在导致的运行时异常。
内容的提问来源于stack exchange,提问作者Hakuna
相关产品推荐
相关产品推荐

