Newtonsoft 转义 JSON 字符串无法反序列化为对象

Posted

技术标签:

【中文标题】Newtonsoft 转义 JSON 字符串无法反序列化为对象【英文标题】:Newtonsoft escaped JSON string unable to deseralize to an object 【发布时间】:2019-02-05 07:20:39 【问题描述】:

问题背景:

我正在通过 HttpResponseMessage 接收 JSON 响应,如图所示:

var jsonString= response.Content.ReadAsStringAsync().Result;

这给了我以下简单的转义 JSON 字符串结果:

"\"\\\"A\\\":\\\"B\\\"\""

问题:

我正在使用 Newtonsoft 尝试将其反序列化为模型:

SimpleModel simpleModel= JsonConvert.DeserializeObject<SimpleModel>(jsonString);

SimpleModel的Class模型:

 public class SimpleModel
 
     public string A  set; get; 
 

转换给我以下错误:

An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Error converting value ""A":"B"" to type 'PyeWebClient.Tests.ModelConversionTests+SimpleModel'. Path '', line 1, position 15.

我从任务结果返回的 JSON 是有效的,所以我不明白是什么问题导致了转换错误,格式化 JSON 字符串的正确方法是什么,以便可以将其转换为 C#型号类型?

【问题讨论】:

是否存在内部异常,可能会提供更多详细信息? 因此,如果您的序列化 JSON 再次被序列化,您也可以反序列化两次:JsonConvert.DeserializeObject&lt;SimpleModel&gt;(JsonConvert.DeserializeObject&lt;string&gt;("\"\\\"A\\\":\\\"B\\\"\""))。当然一开始最好避免序列化两次。 您的源字符串中有多余的引号,它们不是有效的 json。有效的 json 将是 "A":"B",没有双引号包裹它。在反序列化之前删除多余的引号,或者仔细检查@ckuri 提到的序列化步骤 How to safely convert a string containing escaped JSON to valid JSON?的可能重复 【参考方案1】:

你的json出现serialize两次。

1) 所以你必须先反序列化成字符串,然后再反序列化成你的SimpleModel like

string json = "\"\\\"A\\\":\\\"B\\\"\"";

string firstDeserialize = JsonConvert.DeserializeObject<string>(json);

SimpleModel simpleModel = JsonConvert.DeserializeObject<SimpleModel>(firstDeserialize); 

输出:

2)如果您不想反序列化两次,请将您的 json 解析为 JToken,然后再次将其解析为 JObject 之类的

string json = "\"\\\"A\\\":\\\"B\\\"\"";

JToken jToken = JToken.Parse(json);
JObject jObject = JObject.Parse((string)jToken);

SimpleModel simpleModel = jObject.ToObject<SimpleModel>();

输出:

问题:如何序列化两次?

答案:当您从HttpResponseMessage 返回您的结果时,您成功地序列化了您的结果,并且在从ReadAsStringAsync 读取此结果后,此方法再次序列化您已经序列化的结果。

【讨论】:

@Dev,查看答案可能对您有帮助:) 当 json 中的值也包含双引号时,此答案特别有用。在这种情况下,所有需要替换或取消转义的答案都会导致错误。 @exrezzo 很高兴听到 :) 很好的答案!把我从更多的冰雹中救了出来:D【参考方案2】:

您可以将 json 字符串转义为正常字符串,然后使用 DeserializeObject

 string jsonString = "\"\\\"A\\\":\\\"B\\\"\"";

 jsonString = Regex.Unescape(jsonString); //almost there
 jsonString = jsonString.Remove(jsonString.Length - 1, 1).Remove(0,1); //remove first and last qoutes
 SimpleModel simpleModel = JsonConvert.DeserializeObject<SimpleModel>(jsonString);

【讨论】:

以上是关于Newtonsoft 转义 JSON 字符串无法反序列化为对象的主要内容,如果未能解决你的问题,请参考以下文章

使用Newtonsoft.Json.dll序列化和反序列化

newtonsoft.json 反序列化

如何通过NewtonSoft反序列化对象json列表?

使用 Newtonsoft Json 从流中反序列化多个 json 对象

如何使用 newtonsoft json 解决有关无法反序列化当前(例如 “name”:“value”)的难题 [关闭]

Newtonsoft.Json.dll 反序列化JSON字符串