ASP.NET Core API中如何反序列化双重序列化的JSON对象
问题原因
你遇到的是典型的JSON双重序列化问题:上游API返回响应时,先把业务对象序列化为JSON字符串,后续又把这个字符串作为普通值做了第二次序列化,最终返回的内容外层多了一层引号,内部的双引号都被转义,所以无法直接反序列化为目标对象。
另外你的代码里还有异步调用使用不当的问题,直接调用Result容易引发线程死锁,也需要修正。
解决步骤
1. 优先修复上游API(推荐)
这是最根本的解决方案,检查上游用户API的返回逻辑:如果上游也是ASP.NET开发的,大概率是错误地将手动序列化好的JSON字符串直接作为Action返回值,ASP.NET默认会对所有返回值自动做序列化,就会触发二次序列化。修改上游逻辑直接返回业务对象,让框架自动做一次序列化即可。
2. 临时处理双重序列化内容(无法修改上游时用)
如果没有权限修改上游API,可以先对拿到的响应做两次反序列化:第一次把外层的序列化字符串解开拿到原始JSON,第二次再反序列化为目标对象。
修正后的代码如下:
Request.Host = new HostString(_usersApi); HttpRequestMessageFeature hreqmf = new HttpRequestMessageFeature(HttpContext); HttpRequestMessage httpRequestMessage = hreqmf.HttpRequestMessage; // 注意:生产环境不要每次new HttpClient,建议注入IHttpClientFactory创建客户端,避免端口耗尽 var client = new HttpClient(); var response = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead); // 用await异步读取,不要直接调用.Result var rawResponse = await response.Content.ReadAsStringAsync(); // 第一次反序列化拿到原始JSON字符串 var actualJson = JsonConvert.DeserializeObject<string>(rawResponse); // 第二次反序列化为目标对象,配置忽略属性名大小写匹配你的C#类属性命名规则 var deserialized = JsonConvert.DeserializeObject<MyObject>(actualJson, new JsonSerializerSettings { PropertyNameCaseInsensitive = true }); return Ok(deserialized);
额外优化建议
- 全局替换
HttpClient的创建逻辑,用ASP.NET Core内置的IHttpClientFactory管理客户端生命周期,避免长时间运行后出现socket资源耗尽的问题 - 如果后续切换为System.Text.Json做序列化,对应的忽略大小写配置为
JsonSerializerOptions.PropertyNameCaseInsensitive = true
内容的提问来源于stack exchange,提问作者IMOsiris
相关产品推荐
相关产品推荐

