C#运行时报错:JSON反序列化无法将API数据转换为C#对象
核心运行时报错根因
- 反序列化目标类型与实际API响应结构不匹配
当前代码直接将整个接口返回的JSON字符串反序列化为List<MovieResults>,但TMDB的discover/movie接口返回并非数组格式,而是单一层级的对象结构:
由于编译阶段反序列化的输入是纯字符串,IDE无法做静态类型校验,因此不会提前抛出告警;运行时碰到JSON最外层的响应结构示例(简化):
{ "page": 1, "results": [ /* 电影条目数组实际存放在这个字段下 */ ], "total_pages": 500, "total_results": 10000 }{结构无法匹配数组类型,就会直接触发反序列化异常。 - 默认序列化规则不匹配字段命名
内置的System.Text.Json默认对属性名做大小写严格匹配,如果MovieResults模型的属性名与接口返回的蛇形命名(如poster_path、vote_average)不做映射适配,即使外层结构修正,也会出现对象属性全为空的异常。 - 未做请求状态校验
当接口返回4xx/5xx错误时,返回的内容并非标准JSON结构,直接做反序列化也会触发运行时错误。
可直接落地的修复方案
- 新增匹配外层响应的根模型
不要直接反序列化电影列表,先定义匹配接口外层结构的模型类:public class MovieDiscoverResponse { public int Page { get; set; } public int TotalPages { get; set; } public int TotalResults { get; set; } public List<MovieResults> Results { get; set; } } - 调整控制器内的反序列化逻辑
替换原有反序列化代码,适配正确的模型类型,同时开启大小写不敏感匹配降低字段映射出错概率:// 新增序列化配置 var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; // 校验请求是否成功 apiResponse.EnsureSuccessStatusCode(); // 按正确的根模型反序列化 var responseData = JsonSerializer.Deserialize<MovieDiscoverResponse>(apiData, jsonOptions); var movieList = responseData?.Results ?? new List<MovieResults>(); ViewBag.Movie = movieList; - 长期优化建议
- 不要在每次请求时都new一个
HttpClient实例,长期运行会出现套接字耗尽的问题,可以通过依赖注入的方式注入预配置的IHttpClientFactory来统一管理HttpClient实例。 - 当前代码里把
MovieList定义为控制器的公开实例字段属于冗余写法,控制器本身是瞬态的,每次请求都会重新实例化,这个字段没有实际的全局存储作用,移除后直接在方法内处理返回结果即可。
- 不要在每次请求时都new一个
内容的提问来源于stack exchange,提问作者pdrake1988
相关产品推荐
相关产品推荐

