将Amadeus API返回的JSON转换为C#类并在Blazor组件间传递时遇到JSON反序列化错误
将Amadeus API返回的JSON转换为C#类并在Blazor组件间传递时遇到JSON反序列化错误
我一眼就看出问题出在哪了——你把API返回的单个对象当成了对象列表来反序列化!咱们一步步理清楚:
问题核心分析
Amadeus这个API返回的JSON是一个单个的RootObject实例(它里面的data字段才是航班目的地的数组),但你在代码里用List<RootObject>去接收并反序列化,这就和JSON结构完全不匹配,难怪会报“无法转换为List<RootObject>”的错误。
具体修正步骤
1. 修正数据类型定义
首先把组件里的字段和方法返回类型从List<RootObject>改成单个RootObject:
// 原来的List<RootObject>改成可空的RootObject private RootObject? destinations; // 方法返回类型同步改成Task<RootObject?> private async Task<RootObject?> GetMostTravelledDestinations(string accessToken) { // 后续代码跟着调整,下面会详细说明 }
2. 补全C#类的缺失部分
你的C#类里漏了JSON中dictionaries.locations对应的结构,虽然这不是当前报错的直接原因,但为了结构完整避免后续问题,咱们补上这部分:
public class Dictionaries { public Currencies currencies { get; set; } // 补上缺失的locations属性,用字典匹配动态的机场代码键 public Dictionary<string, Location> locations { get; set; } } // 新增Location类对应JSON里的单个机场信息结构 public class Location { public string subType { get; set; } public string detailedName { get; set; } }
(原来的Currencies、RootObject等其他类可以保留,只需要补上面这两块内容)
3. 修正反序列化逻辑
在GetMostTravelledDestinations方法里,把反序列化的目标类型改成RootObject,而不是List<RootObject>,同时建议开启属性名大小写不敏感匹配:
private async Task<RootObject?> GetMostTravelledDestinations(string accessToken) { var request = new HttpRequestMessage(HttpMethod.Get, "https://test.api.amadeus.com/v1/shopping/flight-destinations?origin=MAD"); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); request.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); var response = await Http.SendAsync(request); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); // 反序列化为单个RootObject实例,开启大小写不敏感避免命名问题 return JsonSerializer.Deserialize<RootObject>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } return null; }
4. 组件间传递数据的正确方式
现在destinations是单个RootObject实例,它的data属性才是你要的航班目的地列表。传递给子组件时,直接传这个data数组即可:
<!-- 假设子组件的参数是Data[]或List<Data>类型 --> @if (destinations?.data != null) { <FlightDestinationsList Destinations="destinations.data" /> }
最后验证
当你调用完GetMostTravelledDestinations并赋值给destinations后,destinations.data就是JSON里的航班目的地数组,直接用这个数组去渲染或者传给子组件就没问题了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

