如何用单个方法将JSON字符串(单/多对象)反序列化为泛型类?
通用JSON反序列化方法(支持单个/多个对象)
我明白你想要一个通用的反序列化方法,既能处理单个自定义泛型对象,也能处理集合类型的JSON数据,而且想用同一个方法搞定。我来帮你完善这个方案,先梳理下你的现有代码,再给出完整的实现:
你的现有代码片段
实体类
public class Test { public string userId { get; set; } public string Id { get; set; } }
未完成的反序列化方法
private static async Task<IRestResponse<T>> MapResponse<T>(HttpResponseMessage response) where T : class { var restResponse = new WebApiRestResponse<T> { Content = await response.Content.ReadAsStringAsync(), // 这里是你没写完的逻辑 }; // ... 后续待补全的代码 }
完整实现方案(两种主流JSON库可选)
我们需要让这个方法既能处理T为单个实体(比如Test)的情况,也能处理T为集合(比如List<Test>)的情况,同时做好错误处理。下面分别给出基于Newtonsoft.Json(Json.NET)和System.Text.Json的实现:
方案一:使用Newtonsoft.Json(兼容.NET Framework/.NET Core)
首先确保你的IRestResponse<T>和WebApiRestResponse<T>有正确的定义,然后完善方法:
using Newtonsoft.Json; using System.Net; // 先定义响应接口和实现类(如果还没定义的话) public interface IRestResponse<T> { string Content { get; set; } T Data { get; set; } HttpStatusCode StatusCode { get; set; } bool IsSuccessful { get; set; } string ErrorMessage { get; set; } } public class WebApiRestResponse<T> : IRestResponse<T> { public string Content { get; set; } public T Data { get; set; } public HttpStatusCode StatusCode { get; set; } public bool IsSuccessful { get; set; } public string ErrorMessage { get; set; } } private static async Task<IRestResponse<T>> MapResponse<T>(HttpResponseMessage response) where T : class { var restResponse = new WebApiRestResponse<T> { StatusCode = response.StatusCode, Content = await response.Content.ReadAsStringAsync() }; try { // 先确保HTTP请求成功 response.EnsureSuccessStatusCode(); // 直接反序列化,T可以是单个实体或集合(Json.NET会自动处理) restResponse.Data = JsonConvert.DeserializeObject<T>(restResponse.Content); restResponse.IsSuccessful = true; } catch (HttpRequestException ex) { // 处理HTTP层面的错误(比如404、500) restResponse.IsSuccessful = false; restResponse.ErrorMessage = $"HTTP请求失败: {ex.Message}"; } catch (JsonSerializationException ex) { // 处理JSON格式不匹配、字段缺失等反序列化错误 restResponse.IsSuccessful = false; restResponse.ErrorMessage = $"JSON反序列化失败: {ex.Message}"; } catch (Exception ex) { // 兜底处理其他未知错误 restResponse.IsSuccessful = false; restResponse.ErrorMessage = $"未知错误: {ex.Message}"; } return restResponse; }
方案二:使用System.Text.Json(.NET Core 3.0+/.NET 5+)
如果你的项目用的是较新的.NET版本,推荐用内置的System.Text.Json,不需要额外安装NuGet包:
using System.Text.Json; using System.Net; // 同样先确保响应接口和实现类定义正确 public interface IRestResponse<T> { string Content { get; set; } T Data { get; set; } HttpStatusCode StatusCode { get; set; } bool IsSuccessful { get; set; } string ErrorMessage { get; set; } } public class WebApiRestResponse<T> : IRestResponse<T> { public string Content { get; set; } public T Data { get; set; } public HttpStatusCode StatusCode { get; set; } public bool IsSuccessful { get; set; } public string ErrorMessage { get; set; } } private static async Task<IRestResponse<T>> MapResponse<T>(HttpResponseMessage response) where T : class { var restResponse = new WebApiRestResponse<T> { StatusCode = response.StatusCode, Content = await response.Content.ReadAsStringAsync() }; try { response.EnsureSuccessStatusCode(); // 反序列化时开启忽略大小写,适配JSON字段和类属性的大小写差异 restResponse.Data = JsonSerializer.Deserialize<T>(restResponse.Content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); restResponse.IsSuccessful = true; } catch (HttpRequestException ex) { restResponse.IsSuccessful = false; restResponse.ErrorMessage = $"HTTP请求失败: {ex.Message}"; } catch (JsonException ex) { restResponse.IsSuccessful = false; restResponse.ErrorMessage = $"JSON反序列化失败: {ex.Message}"; } catch (Exception ex) { restResponse.IsSuccessful = false; restResponse.ErrorMessage = $"未知错误: {ex.Message}"; } return restResponse; }
使用示例
不管用哪个方案,调用方式都很简单,只需要指定对应的泛型类型即可:
反序列化单个对象
// 假设你有HttpClient实例 var response = await httpClient.GetAsync("api/test/getSingle"); var restResponse = await MapResponse<Test>(response); if (restResponse.IsSuccessful) { Test singleTest = restResponse.Data; // 在这里处理单个Test对象 } else { // 处理错误,比如打印错误信息 Console.WriteLine(restResponse.ErrorMessage); }
反序列化集合对象
var response = await httpClient.GetAsync("api/test/getList"); var restResponse = await MapResponse<List<Test>>(response); if (restResponse.IsSuccessful) { List<Test> testList = restResponse.Data; // 在这里处理Test集合 } else { Console.WriteLine(restResponse.ErrorMessage); }
内容的提问来源于stack exchange,提问作者user1436795
相关产品推荐
相关产品推荐

