移除JSON反斜杠失败求助:多种方法无效,Postman仍显示反斜杠
我有一个包含反斜杠的JSON字符串:
"{\"multicast_id\":972977234134833616,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1702805668638456%867f64cc867f64cc\"}]}"
尝试了多种方法移除反斜杠均无效,包括:
JToken.Parse(response).ToString()Regex.Unescape(response)- 自定义遍历字符移除反斜杠的方法:
private string RemoveBackslash(string str) { StringBuilder sb = new StringBuilder(); foreach (char c in str) { if (c == '\\') { char ch = c; } else { sb.Append(c); } } return sb.ToString(); }
response = response.Replace("\\", "");
排查后发现,Visual Studio调试器里的反斜杠只是显示效果,实际字符串中不存在,但把响应发送到Postman时,反斜杠真实存在。控制台示例中用JToken.Parse和Replace能正常移除,但实际项目里无效。
项目场景是调用FCM发送推送后获取响应,再封装返回,Postman收到的内容如下:
{ "result": "{\"multicast_id\":1184953349068678451,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1702812609911950%867f64cc867f64cc\"}]}", "error": "" }
完整代码如下:
public FCMPushNotification SendNotification(string _title, string _message, string priority, string _to) { FCMPushNotification result = new FCMPushNotification(); try { result.Successful = true; result.Error = null; var requestUri = "https://fcm.googleapis.com/fcm/send"; WebRequest webRequest = WebRequest.Create(requestUri); webRequest.Method = "POST"; webRequest.Headers.Add(string.Format("Authorization: key={0}", "AAAA10wXm0Yxxxxxxxxxx")); webRequest.ContentType = "application/json"; var data = new { to = _to, priority = priority, notification = new { title = _title, body = _message, } }; string postbody = JsonConvert.SerializeObject(data).ToString(); Byte[] byteArray = Encoding.UTF8.GetBytes(postbody); webRequest.ContentLength = byteArray.Length; using (Stream dataStream = webRequest.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); using (WebResponse webResponse = webRequest.GetResponse()) { using (Stream dataStreamResponse = webResponse.GetResponseStream()) { using (StreamReader tReader = new StreamReader(dataStreamResponse)) { string sResponseFromServer = tReader.ReadToEnd(); result.Response = sResponseFromServer; } } } } } catch (Exception ex) { result.Successful = false; result.Response = null; result.Error = ex; } return result; } [HttpPost] [Route("[action]")] public result SendNotification([FromBody] Notification value) { result rr = new result(); rr.Result = "Error"; rr.Error = ""; SqlConnection con = new SqlConnection(connString); string query = "SELECT UserToken FROM AndroidTokens WHERE UserId='" + value.UserId + "'"; con.Open(); DataTable dt = new DataTable(); SqlDataAdapter adp = new SqlDataAdapter(query, con); adp.Fill(dt); string userToken = string.Empty; if (dt.Rows.Count > 0) { DataRow dr = dt.Rows[0]; userToken = dr["UserToken"].ToString(); } FCMPushNotification fcmPush = new FCMPushNotification(); fcmPush = fcmPush.SendNotification(value.Title, value.Message, value.Priority, userToken); if (fcmPush.Successful) { string response = fcmPush.Response; // 问题出在这里 string token = response.Replace("\\", ""); rr.Result = token; } else { rr.Error = fcmPush.Error.Message; } return rr; }
问题的核心不是字符串里真的有反斜杠,而是你把FCM返回的JSON字符串直接赋值给了rr.Result,当ASP.NET把rr对象序列化为JSON返回时,会把这个字符串里的引号转义,从而产生反斜杠。
正确的做法是把FCM的响应字符串解析成JSON对象,再赋值给返回对象,这样整个响应会是嵌套的JSON结构,而不是字符串嵌套:
修改步骤:
首先,确保你的
result类的Result属性类型不是string,而是object或者对应的强类型(比如可以创建一个FCM响应的实体类)。如果用object,可以直接解析后赋值。修改API方法里的代码:
if (fcmPush.Successful) { // 把FCM的响应字符串解析成JObject(或者对应的实体类) var fcmResponse = JsonConvert.DeserializeObject<JObject>(fcmPush.Response); rr.Result = fcmResponse; // 直接赋值对象,而不是字符串 }
如果要创建强类型,可以定义如下类:
public class FcmResponse { public long multicast_id { get; set; } public int success { get; set; } public int failure { get; set; } public int canonical_ids { get; set; } public List<FcmResult> results { get; set; } } public class FcmResult { public string message_id { get; set; } }
然后解析时用强类型:
var fcmResponse = JsonConvert.DeserializeObject<FcmResponse>(fcmPush.Response); rr.Result = fcmResponse;
这样修改后,Postman收到的响应会是正常的嵌套JSON,没有反斜杠:
{ "result": { "multicast_id": 1184953349068678451, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "0:1702812609911950%867f64cc867f64cc" } ] }, "error": "" }
为什么之前的方法无效?
你之前尝试的Replace("\\", "")或者JToken.Parse(response).ToString(),得到的还是一个字符串,当这个字符串被再次序列化时,引号依然会被转义,所以反斜杠又出现了。只有让返回的对象里包含JSON对象(而非字符串),序列化时才会生成正确的嵌套JSON结构。
内容的提问来源于stack exchange,提问作者Ram

