本地C# Azure Function返回JSON转义双引号问题排查与解决
嗨,我之前也遇到过一模一样的问题,咱们来聊聊这个转义问题的根源和解决办法:
问题成因
你现在的代码是把从第三方API读取到的JSON字符串直接作为字符串参数传给req.CreateResponse,同时指定了"application/json"的Content-Type。这里的坑在于:当CreateResponse接收的参数是string类型时,它会把这个字符串当作JSON的一个字符串字面量来处理——也就是说,框架会把整个字符串包裹在双引号里,并且对字符串内部的双引号进行转义,最终返回的其实是一个包含JSON文本的字符串值,而不是你想要的原生JSON对象。
举个直观的例子:你传入的是"{\"Id\":\"0\"}"(实际读取到的原始字符串),框架会把它处理成"\"{\\\"Id\\\":\\\"0\\\"}\"",所以Postman里看到的就是带转义的结果。
解决方案
有两种简单高效的解决方式,你可以根据场景选择:
方案1:直接转发第三方API的响应内容(推荐,性能最优)
既然你只是做代理,完全不需要解析JSON内容,直接把第三方API的响应内容原封不动地返回即可,这样既避免了转义问题,还省去了序列化/反序列化的性能开销:
HttpResponseMessage response = await _httpClient.PostAsync(requestUri, content); if (response.IsSuccessStatusCode) { // 创建一个新的响应,直接复用第三方API的Content var functionResponse = new HttpResponseMessage(HttpStatusCode.OK); functionResponse.Content = response.Content; // 确保Content-Type是正确的application/json(第三方API一般已经设置好了,保险起见可以手动指定) functionResponse.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); return functionResponse; }
方案2:将JSON字符串反序列化为对象后再返回
如果你需要在返回前对JSON内容做一些修改,或者想保证类型安全,可以先把读取到的JSON字符串反序列化为对象,再传给CreateResponse。框架会自动把对象序列化为正确的JSON,不会出现转义:
用System.Text.Json(.NET Core/.NET 5+默认)的示例:
using System.Text.Json; HttpResponseMessage response = await _httpClient.PostAsync(requestUri, content); if (response.IsSuccessStatusCode) { var jsonResponseBody = await response.Content.ReadAsStringAsync(); // 反序列化为动态对象(如果没有对应实体类)或者具体的实体类 var responseData = JsonSerializer.Deserialize<object>(jsonResponseBody); // 这里传入的是对象,框架会正确序列化为JSON return req.CreateResponse(HttpStatusCode.OK, responseData, "application/json"); }
如果有对应的实体类(比如UserInfo),替换object为你的实体类会更规范,也能获得类型检查的好处。
总结
核心问题就是你传递给CreateResponse的是JSON格式的字符串,而不是JSON对象,框架把字符串当成了JSON的一个值来处理才导致了转义。选择上面两种方案中的任意一种,都能解决这个问题~
内容的提问来源于stack exchange,提问作者KyKo

