ASP.NET Core中如何处理成功/错误状态返回不同对象的REST API
处理REST API响应序列化异常的非try-catch方案
针对你遇到的问题,这里有几个高效的非try-catch处理方案,按推荐优先级排序:
1. 先获取原始响应内容,按状态码分支处理
这是最直接高效的方式,完全规避错误反序列化的场景:
- 先调用客户端获取完整的
HttpResponseMessage,不要直接触发自动反序列化 - 读取响应内容为字符串
- 根据HTTP状态码判断:成功状态码(2xx)时反序列化为目标对象,错误状态码时直接使用字符串作为错误信息
示例代码:
var response = await _customHttpClient.GetAsync("api/target-endpoint"); var responseContent = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { var successResponse = JsonSerializer.Deserialize<YourSuccessResponseClass>(responseContent); // 处理成功逻辑 } else { var errorMessage = responseContent; // 处理错误逻辑,比如记录、返回给上层等 }
2. 扩展自研HttpClient,封装通用响应处理方法
如果需要在多个地方复用这个逻辑,可以给公司的自研HttpClient扩展一个通用方法,把状态判断和反序列化逻辑封装进去:
public static async Task<(T? SuccessResult, string? ErrorMessage)> GetDualResponseAsync<T>(this CustomHttpClient client, string requestUri) { var response = await client.GetAsync(requestUri); var content = await response.Content.ReadAsStringAsync(); return response.IsSuccessStatusCode ? (JsonSerializer.Deserialize<T>(content), null) : (default, content); }
业务代码里调用时就很简洁:
var (successObj, errorMsg) = await _customHttpClient.GetDualResponseAsync<YourSuccessResponseClass>("api/target-endpoint"); if (successObj != null) { // 成功逻辑 } else { // 处理错误信息 }
3. 自定义JSON转换器兼容两种格式
如果必须要直接使用客户端的反序列化方法,可以给成功响应类写一个自定义转换器,在序列化时自动兼容字符串错误:
public class DualModeConverter : JsonConverter<YourSuccessResponseClass> { public override YourSuccessResponseClass? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { try { // 尝试反序列化为成功对象 return JsonSerializer.Deserialize<YourSuccessResponseClass>(ref reader, options); } catch (JsonException) { // 失败则读取错误字符串,这里可以根据需求存储错误信息 var errorMsg = reader.GetString(); // 可以通过额外的上下文传递错误,比如静态变量、自定义属性等 return null; } } public override void Write(Utf8JsonWriter writer, YourSuccessResponseClass value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }
使用时把转换器加入序列化选项:
var serializerOptions = new JsonSerializerOptions(); serializerOptions.Converters.Add(new DualModeConverter()); var result = await _customHttpClient.GetFromJsonAsync<YourSuccessResponseClass>("api/target-endpoint", serializerOptions); if (result != null) { // 成功逻辑 } else { // 处理错误 }
注意:这个方案的性能略低于前两种,因为会有一次失败的序列化尝试,所以优先推荐前两种基于状态码判断的方案。
内容的提问来源于stack exchange,提问作者Dogan Cignakli
相关产品推荐
相关产品推荐

