C#调用Custom Vision接口JSON反序列化为List<Project>报错如何解决
错误产生原因
这个异常的核心触发逻辑是:JsonConvert.DeserializeObject反序列化时期待根节点为JSON数组(对应C#中的List<Project>类型,JSON格式以[开头),但接口实际返回的响应根节点是单个JSON对象(格式以{开头),类型完全不匹配。
结合你调用Custom Vision接口的场景,常见的具体诱因有三个:
- 代码未校验HTTP请求状态,当接口返回鉴权失败、参数错误、资源不存在等错误响应时,错误体本身就是单个JSON对象(一般包含错误码、错误信息字段),不是你预期的项目列表数组,直接反序列化必然报错。比如Training-Key填错、密钥和终结点所属区域不匹配时,接口会直接返回401错误对象。
- 接口地址拼接错误,比如路径中把
projects误写为project、终结点结尾多拼/漏拼路径字符,命中了返回单个对象的其他接口,而非返回全量项目列表的接口。 - 部分区域/版本的Custom Vision列表接口返回结果存在外层包装,根节点是一个包含
value字段的对象,项目数组实际存放在value属性下,而非直接作为根节点返回。
修复方案
按以下步骤排查处理即可:
- 先在反序列化前打印原始
responseContent内容,确认实际返回的JSON结构,不要默认接口一定返回符合预期的项目列表。- 如果打印内容是错误提示(比如密钥无效、权限不足),优先修正配置:确认填入的
_apiKey是训练密钥而非预测密钥,CustomVisionEndpoint和密钥所属资源的区域完全匹配。 - 如果返回内容是带外层包装的结构(类似
{"value": [项目1, 项目2...]}),先定义对应的响应包装类,再调整反序列化逻辑:public class CustomVisionProjectListResp { public List<Project> Value { get; set; } } // 反序列化逻辑替换为 var listResp = JsonConvert.DeserializeObject<CustomVisionProjectListResp>(responseContent); var projects = listResp.Value;
- 如果打印内容是错误提示(比如密钥无效、权限不足),优先修正配置:确认填入的
- 补充HTTP响应状态校验逻辑,不要在请求失败的场景下继续执行反序列化。修改请求部分代码如下:
using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri)) { requestMessage.Headers.Add("Training-Key", _apiKey); var response = Client.SendAsync(requestMessage).Result; // 请求失败时直接抛出包含错误详情的异常,避免后续类型不匹配 if (!response.IsSuccessStatusCode) { string errorMsg = response.Content.ReadAsStringAsync().Result; throw new InvalidOperationException($"调用Custom Vision接口失败,状态码:{response.StatusCode},详情:{errorMsg}"); } responseContent = response.Content.ReadAsStringAsync().Result; } - 核对接口地址格式,确认使用的是v3.0版本获取项目列表的正确路径:
{CustomVisionEndpoint}/customvision/v3.0/training/projects,不要出现路径拼写错误。
内容的提问来源于stack exchange,提问作者yerraboi
相关产品推荐
相关产品推荐

