.NET 6中API JSON响应反序列化问题求助
问题:.NET 6中航班API JSON反序列化错误及程序冻结问题
- 反序列化时触发
JsonException,错误提示lat字段无法转换为FlightData类型 - 提取
response字段后程序出现冻结
错误原因分析
- 类型不匹配:API返回的
lat、lng、alt等字段是数字类型(浮点数/整数),但FlightData类中这些属性被定义为string类型,无法直接完成转换。 - 错误的文件读取操作:代码中使用
File.ReadAllText(responseData.ToString()),此处responseData.ToString()返回的是JSON数组的文本内容,而File.ReadAllText会将该文本当作文件路径去读取,导致程序尝试访问不存在的文件,引发资源占用或无限等待,最终冻结。 - 缺失无参数构造函数:
FlightData类仅定义了带参数的构造函数,而System.Text.Json默认需要无参数构造函数才能正确实例化对象。
解决方案
1. 修正FlightData类的属性类型与构造函数
将数字类型的属性改为对应的值类型,并添加无参数构造函数:
internal class FlightData { public string? hex { get; set; } public string? reg_number { get; set; } public string? flag { get; set; } public double? lat { get; set; } public double? lng { get; set; } public int? alt { get; set; } public int? dir { get; set; } public int? speed { get; set; } public double? v_speed { get; set; } public string? squawk { get; set; } public string? flight_number { get; set; } public string? flight_icao { get; set; } public string? flight_iata { get; set; } public string? dep_icao { get; set; } public string? dep_iata { get; set; } public string? airline_icao { get; set; } public string? airline_iata { get; set; } public string? aircraft_icao { get; set; } public long? updated { get; set; } public string? status { get; set; } // 添加无参数构造函数,满足反序列化要求 public FlightData() {} // 保留带参数构造函数(若业务需要) public FlightData(string hex, string reg_number, string flag, double? lat, double? lng, int? alt, int? dir, int? speed, double? v_speed, string flight_number, string flight_icao, string flight_iata, string dep_icao, string dep_iata, string airline_icao, string airline_iata, string aircraft_icao, long? updated, string status) { this.hex = hex; this.reg_number = reg_number; this.flag = flag; this.lat = lat; this.lng = lng; this.alt = alt; this.dir = dir; this.speed = speed; this.v_speed = v_speed; this.flight_number = flight_number; this.flight_icao = flight_icao; this.flight_iata = flight_iata; this.dep_icao = dep_icao; this.dep_iata = dep_iata; this.airline_icao = airline_icao; this.airline_iata = airline_iata; this.aircraft_icao = aircraft_icao; this.updated = updated; this.status = status; } }
2. 修正API响应处理逻辑
移除错误的文件读取操作,直接从JsonElement完成反序列化,同时兼容两种API响应格式:
using System.Net.Http.Headers; using System.Text.Json; using System.Text.Json.Serialization; using System.Net.Http.Json; using System.Net; using HttpClient client = new(); await ProcessRepositoriesAsync(client); static async Task ProcessRepositoriesAsync(HttpClient client) { string apiUrl = "<<API CALL URL WITH AUTHENTICATION KEY>>"; try { string jsonResponse = await client.GetStringAsync(apiUrl); var jsonDocument = JsonDocument.Parse(jsonResponse); List<FlightData> flightList = new(); var deserializeOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, // 兼容字段大小写不匹配的情况 IgnoreUnknownFields = true // 忽略API返回中未定义的字段(如arr_icao) }; if (jsonDocument.RootElement.TryGetProperty("response", out var responseData)) { // 处理含元数据的响应,直接反序列化response字段 flightList = responseData.Deserialize<List<FlightData>>(deserializeOptions) ?? new List<FlightData>(); } else { // 处理无元数据的直接数组响应 flightList = jsonDocument.RootElement.Deserialize<List<FlightData>>(deserializeOptions) ?? new List<FlightData>(); } foreach (var flight in flightList) { Console.WriteLine($"Flight Number: {flight.flight_number}, Altitude: {flight.alt}, Flag: {flight.flag}"); } } catch (HttpRequestException ex) { Console.WriteLine($"Request Error: {ex.Message}"); } catch (JsonException ex) { Console.WriteLine($"JSON Deserialization Error: {ex.Message}"); } }
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

