Refit中包装ApiResponse<T>方法无法获取内容的问题排查
Refit ApiResponse 包装问题解决方案
为什么转换后得到null?
你的泛型参数逻辑完全搞反了。看你的调用代码:
ApiResponse<GetCustomerResponse> response = await ExecuteAsync(() => webApiClient.GetCustomers())
这里ExecuteAsync的泛型参数T会被自动推断为ApiResponse<GetCustomerResponse>,所以方法里的ApiResponse<T>实际是ApiResponse<ApiResponse<GetCustomerResponse>>——而你从委托拿到的apiResponse是ApiResponse<GetCustomerResponse>类型,用as转换必然返回null,因为两者根本不是同一类型。
正确的ApiResponse包装方法
你需要调整泛型参数,让ExecAsync接收返回Task<ApiResponse<T>>的委托,泛型参数T对应ApiResponse内部的内容类型:
public async Task<ApiResponse<T>> ExecAsync<T>(Func<Task<ApiResponse<T>>> method) where T : class { ApiResponse<T> apiResponse = await method.Invoke(); if (apiResponse.IsSuccessStatusCode) { // 执行成功逻辑,比如记录请求成功日志 return apiResponse; } else { // 执行失败逻辑,比如记录错误状态码、响应详情 // 示例:_logger.LogError("请求失败,状态码:{StatusCode}", apiResponse.StatusCode); return apiResponse; } }
调用方式无需修改,泛型参数会自动匹配GetCustomerResponse:
ApiResponse<GetCustomerResponse> response = await ExecAsync(() => webApiClient.GetCustomers());
如何直接返回ApiResponse.Content?
如果业务逻辑只需要响应内容,不需要整个ApiResponse对象,可以修改方法返回T,同时处理失败场景:
public async Task<T> ExecAsync<T>(Func<Task<ApiResponse<T>>> method) where T : class { ApiResponse<T> apiResponse = await method.Invoke(); if (apiResponse.IsSuccessStatusCode) { return apiResponse.Content; } else { // 失败时可选择记录日志、抛出自定义异常或返回null // 示例:_logger.LogError("请求失败,状态码:{StatusCode},错误信息:{Message}", apiResponse.StatusCode, apiResponse.ErrorMessage); // throw new ApiRequestException(apiResponse.StatusCode, apiResponse.ErrorMessage); return null; } }
调用时直接获取内容:
GetCustomerResponse responseContent = await ExecAsync(() => webApiClient.GetCustomers());
额外提示
- Refit的
ApiResponse<T>包含了状态码、响应内容、错误信息等完整请求结果,包装时务必确保泛型参数对应正确的内容类型,避免嵌套错误。 - 如果你的接口存在返回非泛型
ApiResponse的情况,可以重载ExecAsync方法适配这种场景。
内容的提问来源于stack exchange,提问作者developer9969
相关产品推荐
相关产品推荐

