如何处理成功与失败返回不同响应结构的第三方WEB API?
解决方案
你遇到的问题根源是直接使用泛型ExecuteAsync<T>时,返回的错误数组无法反序列化到预期的成功对象类型,因此需要先拿到原始响应内容自行判断结构后再做反序列化,具体处理步骤如下:
1 定义所需实体类
首先定义成功响应、错误项以及你内部统一使用的响应包装类:
// 接口成功返回的结构 public class SuccessApiResponse { public string message { get; set; } public string jobNr { get; set; } public string status { get; set; } } // 供应商返回的错误项结构 public class ApiErrorItem { public int code { get; set; } public string message { get; set; } } // 内部统一使用的响应包装类,方便业务层统一处理 public class ApiCallResult<T> { public T Data { get; set; } public List<ApiErrorItem> Errors { get; set; } // 便捷判断请求是否成功 public bool IsSuccess => Errors == null || Errors.Count == 0; }
2 调整接口调用逻辑
不要直接使用泛型ExecuteAsync<T>,先调用无泛型方法拿到原始响应内容,再判断JSON结构做对应反序列化:
// 第一步:先获取原始响应,不提前反序列化 IRestResponse rawResponse = await restClient.ExecuteAsync(request); var result = new ApiCallResult<SuccessApiResponse>(); // 处理响应为空的异常情况 if (string.IsNullOrWhiteSpace(rawResponse.Content)) { result.Errors = new List<ApiErrorItem> { new ApiErrorItem { code = -1, message = "接口返回空响应" } }; return result; } var content = rawResponse.Content.Trim(); // 第二步:判断JSON结构类型 if (content.StartsWith("[")) { // 是错误数组,反序列化为错误列表 result.Errors = JsonConvert.DeserializeObject<List<ApiErrorItem>>(content); } else if (content.StartsWith("{")) { // 是成功对象,反序列化为成功响应类 result.Data = JsonConvert.DeserializeObject<SuccessApiResponse>(content); } else { result.Errors = new List<ApiErrorItem> { new ApiErrorItem { code = -2, message = "接口返回非JSON格式内容" } }; } // 后续可以正常使用result的IsSuccess、Data、Errors属性做业务处理
注:上述代码使用Newtonsoft.Json做反序列化,如果你项目中用System.Text.Json,替换对应反序列化方法即可。也可以结合HTTP状态码做双重校验,比如状态码为200时再反序列化为成功对象,非200时直接尝试反序列化为错误列表,兼容性更高。
3 可选优化:封装通用扩展方法
你可以把上述逻辑封装为RestClient的通用扩展方法,后续调用和原有泛型方法一样便捷,无需重复写判断逻辑:
public static async Task<ApiCallResult<T>> ExecuteCustomAsync<T>(this IRestClient client, IRestRequest request) { // 把上述第二步的逻辑封装进来,把SuccessApiResponse替换为泛型T即可 }
内容的提问来源于stack exchange,提问作者Nmaster88
相关产品推荐
相关产品推荐

