C# Newtonsoft Json Converter:动态反序列化泛型为具体类型
当然可以搞定!在C#里,不管你用的是老牌的Newtonsoft.Json还是.NET Core之后默认的System.Text.Json,都能轻松实现把API返回的动态Data字段反序列化成你指定的具体类型(比如带Name、Email属性的Person类)。下面给你两种主流序列化库的具体实现方案:
方案一:使用Newtonsoft.Json(Json.NET)
首先先定义好基础的类结构:
// API响应的基础结构 public class ApiResponse { public int Code { get; set; } public string Message { get; set; } public object Data { get; set; } } // 你需要转换的目标类型 public class Person { public string Name { get; set; } public string Email { get; set; } }
方法1:手动解析转换(适合偶尔使用)
先把整个JSON反序列化为JObject,再手动提取字段并把Data部分转换为Person类型:
// 示例API返回的JSON字符串 var apiJson = @"{""Code"":200,""Message"":""请求成功"",""Data"":{""Name"":""张三"",""Email"":""zhangsan@example.com""}}"; // 解析为JObject var jObj = JObject.Parse(apiJson); // 构建ApiResponse并转换Data类型 var response = new ApiResponse { Code = (int)jObj["Code"], Message = (string)jObj["Message"], Data = jObj["Data"].ToObject<Person>() // 这里指定转换为Person };
方法2:自定义Json转换器(适合频繁使用多种类型)
如果需要经常处理不同类型的Data,写一个泛型转换器会更高效,这样可以直接反序列化整个ApiResponse:
public class ApiResponseConverter<T> : JsonConverter<ApiResponse> { public override ApiResponse ReadJson(JsonReader reader, Type objectType, ApiResponse existingValue, bool hasExistingValue, JsonSerializer serializer) { var jObj = JObject.Load(reader); return new ApiResponse { Code = (int)jObj["Code"], Message = (string)jObj["Message"], Data = jObj["Data"].ToObject<T>(serializer) // 自动转换为指定的T类型 }; } // 如果不需要序列化ApiResponse,可以留空这个方法 public override void WriteJson(JsonWriter writer, ApiResponse value, JsonSerializer serializer) { throw new NotImplementedException(); } }
使用转换器的方式也很简单:
var response = JsonConvert.DeserializeObject<ApiResponse>(apiJson, new ApiResponseConverter<Person>());
方案二:使用System.Text.Json(.NET Core/.NET 5+ 默认)
同样先定义类结构:
public class ApiResponse { public int Code { get; set; } public string Message { get; set; } public object Data { get; set; } } public class Person { public string Name { get; set; } public string Email { get; set; } }
方法1:手动解析JsonElement
和Newtonsoft的思路类似,先解析为JsonDocument,再提取字段转换Data:
var apiJson = @"{""Code"":200,""Message"":""请求成功"",""Data"":{""Name"":""张三"",""Email"":""zhangsan@example.com""}}"; using var jsonDoc = JsonDocument.Parse(apiJson); var root = jsonDoc.RootElement; var response = new ApiResponse { Code = root.GetProperty("Code").GetInt32(), Message = root.GetProperty("Message").GetString(), Data = root.GetProperty("Data").Deserialize<Person>() // 指定转换为Person };
方法2:自定义Json转换器
同样可以写一个泛型转换器,实现自动转换:
public class ApiResponseConverter<T> : JsonConverter<ApiResponse> { public override ApiResponse Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using var jsonDoc = JsonDocument.ParseValue(ref reader); var root = jsonDoc.RootElement; return new ApiResponse { Code = root.GetProperty("Code").GetInt32(), Message = root.GetProperty("Message").GetString(), Data = root.GetProperty("Data").Deserialize<T>(options) }; } public override void Write(Utf8JsonWriter writer, ApiResponse value, JsonSerializerOptions options) { throw new NotImplementedException(); } }
使用时添加转换器到序列化选项:
var options = new JsonSerializerOptions(); options.Converters.Add(new ApiResponseConverter<Person>()); var response = JsonSerializer.Deserialize<ApiResponse>(apiJson, options);
额外优化:泛型Response类(更优雅的方案)
如果你的场景允许,直接定义泛型的ApiResponse类会更简洁,不需要额外的转换器:
public class ApiResponse<T> { public int Code { get; set; } public string Message { get; set; } public T Data { get; set; } }
反序列化的时候直接指定类型即可:
// Newtonsoft.Json var response = JsonConvert.DeserializeObject<ApiResponse<Person>>(apiJson); // System.Text.Json var response = JsonSerializer.Deserialize<ApiResponse<Person>>(apiJson);
这种方式类型安全,代码也更简洁,推荐在不需要兼容多种动态Data类型的场景下使用。
内容的提问来源于stack exchange,提问作者2Fast4YouBR
相关产品推荐
相关产品推荐

