如何在C#中反序列化含转义字符的异常JSON格式
为什么Newtonsoft JSON序列化后出现大量转义斜杠,导致客户端反序列化失败?
这种问题我之前踩过好几次,核心原因几乎都是双重序列化——你把同一个对象(或者序列化后的JSON字符串)重复做了两次JSON序列化操作,才会出现这种满是\"的转义字符,还在外层多套了一层引号的情况。
具体原因分析
你看返回的响应:外层是一个带引号的字符串,里面原本的JSON结构里的所有双引号都被转义成了\"。这说明你大概率做了以下操作:
- 先用
JsonConvert.SerializeObject(yourData)把业务对象转换成了标准的JSON字符串; - 然后又把这个已经是字符串的结果,再次传给了另一个序列化机制(比如Web API的
Json()方法、或者你手动又调用了一次SerializeObject)。
第二次序列化的时候,程序会把这个JSON字符串当成一个普通的字符串值来处理,所以会给它套上外层引号,同时把字符串内部的所有双引号都转义,最终就出现了你看到的格式错误。
举个错误代码的例子,很多人在Web API里会不小心这么写:
public IHttpActionResult GetLogisticData() { // 构建业务数据对象 var responseData = new { Data = new List<LogisticItem> { /* 你的数据内容 */ }, Code = 10, Message = "Data retrieved" }; // 第一次序列化:得到标准JSON字符串 string jsonString = JsonConvert.SerializeObject(responseData); // 错误:这里的Json()方法会把jsonString当成普通字符串再序列化一次 return Json(jsonString); }
解决办法
1. 最直接:避免双重序列化,只做一次
如果你用的是Web API或者类似的框架,直接返回业务对象就好,框架会自动帮你完成一次序列化,不需要手动先转成字符串:
public IHttpActionResult GetLogisticData() { var responseData = new { Data = new List<LogisticItem> { /* 你的数据内容 */ }, Code = 10, Message = "Data retrieved" }; // 直接返回对象,框架自动处理序列化 return Ok(responseData); }
2. 如果必须手动序列化(比如自定义响应)
确保只执行一次SerializeObject,然后直接把这个字符串作为响应体返回,不要再次经过序列化流程:
var responseData = new { Data = new List<LogisticItem> { /* 你的数据内容 */ }, Code = 10, Message = "Data retrieved" }; string jsonString = JsonConvert.SerializeObject(responseData); // 直接输出这个字符串,不要再次序列化 Response.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
3. 临时修复客户端(不推荐,治标不治本)
如果服务端暂时没法改,客户端可以先处理这个错误格式的字符串:
- 去掉首尾的外层引号;
- 把所有的
\"替换成"; - 然后再反序列化处理。
但还是强烈建议从服务端解决,毕竟双重序列化是根源问题。
内容的提问来源于stack exchange,提问作者Mr. Developer
相关产品推荐
相关产品推荐

