使用FOR JSON AUTO返回JSON时,ADO.NET获取结果含转义符致JSON无效问题
FOR JSON AUTO生成JSON在C#中重复序列化的问题解决
问题现象
- 在SSMS中执行存储过程,返回的JSON格式正常,无转义反斜杠
- 通过C# ADO.NET查询时,返回结果包含转义反斜杠
- 用Controller返回
JsonResult到前端时,出现Unexpected token 'S'的JSON解析错误 - 尝试字符串替换转义符,问题未解决
核心原因
重复序列化:SQL的FOR JSON AUTO已经生成了完整的合法JSON字符串,但C#中如果将该字符串传入JsonResult,ASP.NET会把它当作普通字符串再次序列化,导致JSON被包裹在引号中,内部的双引号被转义,前端拿到的是一个字符串类型值而非JSON对象,自然解析失败。
解决方法
方法1:直接返回原始JSON字符串(推荐)
不要使用JsonResult,改用ContentResult直接返回SQL生成的原始JSON,并指定正确的Content-Type。
方法2:避免ADO.NET/EF对结果的额外处理
确保从数据库获取的是原始JSON字符串,而非被二次处理的内容。
代码示例
翻译后的中文SQL存储过程
-- 获取任务分配信息存储过程 CREATE PROCEDURE [dbo].[获取任务分配信息] AS BEGIN SET NOCOUNT ON; -- 查询任务表及关联用户表,自动生成嵌套JSON结构 SELECT 任务表.任务ID, 任务表.标题, 任务表.描述, 用户表.用户ID, 用户表.用户名, 用户表.邮箱 FROM 任务表 LEFT JOIN 用户表 ON 任务表.分配用户ID = 用户表.用户ID FOR JSON AUTO; END
修正后的C#代码
ADO.NET查询方法
// 执行存储过程获取原始JSON字符串 public string 获取任务分配JSON(string 存储过程名) { using (var 连接 = new SqlConnection(_连接字符串)) { 连接.Open(); using (var 命令 = new SqlCommand(存储过程名, 连接)) { 命令.CommandType = CommandType.StoredProcedure; // 直接获取SQL生成的JSON结果 var 结果 = 命令.ExecuteScalar()?.ToString(); return 结果 ?? string.Empty; } } }
Controller方法(返回原始JSON)
public IActionResult 获取任务分配() { var 原始JSON = _数据访问层.获取任务分配JSON("获取任务分配信息"); // 直接返回JSON字符串,指定Content-Type为application/json return Content(原始JSON, "application/json"); }
EF Core 版本
// DbContext中获取原始JSON的方法 public string 获取任务分配JSON() { var json = this.Database.SqlQueryRaw<string>("EXEC 获取任务分配信息").FirstOrDefault(); return json ?? string.Empty; }
错误做法说明
不要尝试用字符串替换转义符(比如Replace("\\", "")),这种方法会破坏合法的转义字符(比如JSON字符串中包含的双引号),导致新的JSON格式错误。
内容的提问来源于stack exchange,提问作者Seyi Agboola
相关产品推荐
相关产品推荐

