如何将API返回JSON反序列化为C#自定义Result类并提取指定字段?
解决方案
首先解决你代码中的类命名冲突问题:你定义了两个同名的Result类,这在C#中是不允许的,需要将顶层的JSON容器类重命名(比如ApiResponse),然后单独定义用于存储目标字段的Result类。
下面提供两种常用的实现方案,分别基于主流的JSON序列化库:
方案一:使用Newtonsoft.Json(Json.NET)
这是.NET生态中使用最广泛的JSON处理库,支持直接通过属性路径映射嵌套字段,非常简便。
1. 定义正确的类结构
// 顶层JSON容器类,对应返回的整个JSON结构 public class ApiResponse { // 映射JSON中的"result"数组字段 [JsonProperty("result")] public List<Result> Results { get; set; } } // 存储你需要的目标字段的类 public class Result { // 直接映射嵌套路径:Asset -> AssetName [JsonProperty("Asset.AssetName")] public string AssetName { get; set; } // 映射嵌套路径:Asset -> Hardware -> SystemId [JsonProperty("Asset.Hardware.SystemId")] public string SystemId { get; set; } // 映射嵌套路径:Location -> Lat,用可空类型适配JSON中的null值 [JsonProperty("Location.Lat")] public double? Lat { get; set; } // 映射嵌套路径:Location -> Lng [JsonProperty("Location.Lng")] public double? Lng { get; set; } // 映射根节点的Timestamp字段,自动转换为DateTime类型 [JsonProperty("Timestamp")] public DateTime Timestamp { get; set; } }
2. 反序列化代码
// 假设jsonString是你从API获取的JSON字符串 string jsonString = "你的API返回JSON"; // 反序列化到ApiResponse,直接得到Result列表 var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(jsonString); List<Result> targetResults = apiResponse.Results;
方案二:使用System.Text.Json(.NET Core/.NET 5+ 内置)
如果你使用的是较新版本的.NET,无需额外安装库,直接用内置的System.Text.Json即可(.NET 6及以上支持JsonPath路径映射)。
1. 定义正确的类结构
public class ApiResponse { [JsonPropertyName("result")] public List<Result> Results { get; set; } } public class Result { [JsonPropertyName("Asset.AssetName")] public string AssetName { get; set; } [JsonPropertyName("Asset.Hardware.SystemId")] public string SystemId { get; set; } [JsonPropertyName("Location.Lat")] public double? Lat { get; set; } [JsonPropertyName("Location.Lng")] public double? Lng { get; set; } [JsonPropertyName("Timestamp")] public DateTime Timestamp { get; set; } }
2. 反序列化代码
string jsonString = "你的API返回JSON"; // 配置忽略大小写(避免JSON字段大小写和C#属性不一致的问题) var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var apiResponse = JsonSerializer.Deserialize<ApiResponse>(jsonString, options); List<Result> targetResults = apiResponse.Results;
方案三:轻量提取(无需定义容器类)
如果你只想快速提取目标字段,不想定义完整的类结构,可以用LINQ to JSON直接解析:
Newtonsoft.Json版本
string jsonString = "你的API返回JSON"; JObject jObject = JObject.Parse(jsonString); List<Result> targetResults = jObject["result"] .Select(item => new Result { AssetName = item["Asset"]["AssetName"].ToString(), SystemId = item["Asset"]["Hardware"]["SystemId"].ToString(), Lat = item["Location"]["Lat"].Value<double?>(), Lng = item["Location"]["Lng"].Value<double?>(), Timestamp = item["Timestamp"].Value<DateTime>() }) .ToList();
System.Text.Json版本
string jsonString = "你的API返回JSON"; using JsonDocument doc = JsonDocument.Parse(jsonString); JsonElement root = doc.RootElement; JsonElement resultArray = root.GetProperty("result"); List<Result> targetResults = new List<Result>(); foreach (JsonElement item in resultArray.EnumerateArray()) { targetResults.Add(new Result { AssetName = item.GetProperty("Asset").GetProperty("AssetName").GetString(), SystemId = item.GetProperty("Asset").GetProperty("Hardware").GetProperty("SystemId").GetString(), Lat = item.GetProperty("Location").GetProperty("Lat").ValueKind == JsonValueKind.Null ? null : item.GetProperty("Location").GetProperty("Lat").GetDouble(), Lng = item.GetProperty("Location").GetProperty("Lng").ValueKind == JsonValueKind.Null ? null : item.GetProperty("Location").GetProperty("Lng").GetDouble(), Timestamp = item.GetProperty("Timestamp").GetDateTime() }); }
内容的提问来源于stack exchange,提问作者B.j
相关产品推荐
相关产品推荐

