我一直在测试在后台动态处理json,而不使用对象(因为我不知道对象的结构,而且为将要建立的数千个连接创建它们完全是浪费时间(。我希望能够编程一个接口,而不必自定义我将要连接的每个rest接口的代码,并将数据交给技术人员,而不是像我这样的程序员。
在与NewtonSoft.Json的游戏中,我逐渐意识到有一些奇怪的事情我不太理解,我并不是唯一一个这样做的人,因为我看到许多人写下了类似的问题,但没有解决或理解正在发生的事情。
我在这里发现了许多问题,这些问题将DeserializeObject称为返回带有一组额外大括号的JObject。
示例:
字符串"data"包含以下内容:
{rn "firstName": "John",rn "lastName": "Doe",rn "IDNum": 123456,rn "phoneNumbers": [rn {rn "number": "6123334444"rn },rn {rn "number": "7635556666"rn }rn ]rn}
JObject rest = JsonConvert.DeserializeObject<dynamic>(data.ToString());
但是JObject"rest"得到了一组额外的花括号:
{{
"firstName": "John",
"lastName": "Doe",
"IDNum": 123456,
"phoneNumbers": [
{
"number": "6123334444"
},
{
"number": "7635556666"
}
]
}}
使此JArray命令不起作用:
JArray obj = JArray.Parse(rest ) as JArray;
这里的一篇帖子提到将其转换回字符串,并只替换像这样的大括号:
string cleanRest = rest.ToString().Replace("{{", "{").Replace("}}", "}");
它在字符串"cleanRest"中结束:
{rn "firstName": "John",rn "lastName": "Doe",rn "IDNum": 123456,rn "phoneNumbers": nullrn}
当然cleanRest不是一个有效的json,当运行以下行时,该行抛出错误:"Newtonsoft.json.JsonReaderException:'从JsonReader读取JArray时出错。当前JsonReader项不是数组:StartObject.Path'',第1行,位置1'":
JArray obj = JArray.Parse(cleanRest) as JArray;
我首先遇到的问题包括xmlns:http://schemas.microsoft.com/2003/10/Serialization我不得不将其作为XmlDocument打开,并使用以下内容进行转换:
private string returnJson(string response)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(response);
return doc.DocumentElement.FirstChild.InnerText;
}
但是,尽管我读过一些博客,提到json的MS实现有这样奇怪的怪癖,但所有这些纠缠让我觉得我没有正确处理这个问题。但我不应该修正这种反应;这让我对未来的问题感到紧张。
有人知道发生了什么以及如何解决吗?
因此,解析JSON字符串不会为您提供另一个可以解析的字符串。它会创建一个对象。它需要再次序列化。它工作正常。
但是,字符串表示的对象不是数组。如果您序列化它并将其传递给JArray.parse,它将给出一个错误,因为它不是数组。
实际上,您可以使用ToString序列化rest
,但仅仅将rest
传递给JArray.parse不会编译,所以请确定您真正在做什么。
以下是一些适用于的代码
public static void Main()
{
var json = "{rn "firstName": "John",rn "lastName": "Doe",rn "IDNum": 123456,rn "phoneNumbers": [rn {rn "number": "6123334444"rn },rn {rn "number": "7635556666"rn }rn ]rn}";
JObject rest = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(rest.ToString());
// this works, since phoneNumbers is an array
JArray obj = JArray.Parse(rest["phoneNumbers"].ToString()) as JArray;
// this fails because an object is not an array
obj = JArray.Parse(rest.ToString()) as JArray;
}
如果您想访问属性,如果您知道名称(即rest["phoneNumbers"]
(,则可以使用数组语法。或者,如果你不知道它有什么属性,你可以这样做:
foreach (var x in rest)
{
string name = x.Key;
JToken value = x.Value;
}
您也可以更改值:
rest["firstName"] = "My New Name";
或添加新的
rest["newproperty"] = 2500;