问题描述
在这一行代码上:
var arr = JsonConvert.DeserializeObject<JArray>(s);
...我得到的是,“ 无法将类型为'Newtonsoft.Json.Linq.JObject'的对象转换为类型为'Newtonsoft.Json.Linq.JArray'。”
我将该行更改为此:
JArray arr = JsonConvert.DeserializeObject<JArray>(s);
...并获得相同的错误信息。
我将其更改为:
var arr = JsonConvert.DeserializeObject<JObject>(s);
...甚至无法编译。
此时调用已读取的内容(在字符串s中)为:
{"id":347745,"results":[{"iso_3166_1":"US","release_dates":[{"certification":"","iso_639_1":"","note":"","release_date":"1936-12-12T00:00:00.000Z","type":3}]}]}
我所需要的只是“认证”的值;在这种情况下,证书值为空字符串(“ certification”:“”)
在上下文中,代码为:
. . .
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(RESTStringToGetMPAARatingForMovieId);
webRequest.Method = "GET";
var webResponse = (HttpWebResponse)webRequest.GetResponse();
if ((webResponse.StatusCode == HttpStatusCode.OK) && (webResponse.ContentLength > 0))
{
StreamReader streamReader = new StreamReader(webResponse.GetResponseStream());
string s = streamReader.ReadToEnd();
var arr = JsonConvert.DeserializeObject<JArray>(s);
//JArray arr = JsonConvert.DeserializeObject<JArray>(s);
//var arr = JsonConvert.DeserializeObject<JObject>(s);
foreach (JObject obj in arr)
{
_currentMPAARating = (string)obj["certification"];
. . .
}
}
else
{
MessageBox.Show(string.Format("Status code == {0},Content length == {1}",webResponse.StatusCode,webResponse.ContentLength));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
解决方法
您的JSON不是数组,它是包含数组(results
)的对象。但这实际上比这更复杂:您要搜索的certification
字符串被嵌套在另一个release_dates
数组中。
如果您使用JSON并使用JSON验证器/美化器将其重新格式化,则它应该变得更加清晰:
{
"id": 347745,"results": [
{
"iso_3166_1": "US","release_dates": [
{
"certification": "","iso_639_1": "","note": "","release_date": "1936-12-12T00:00:00Z","type": 3
}
]
}
]
}
因此,要使用常规foreach
循环获取所需的数据,您将需要以下代码:
var obj = JsonConvert.DeserializeObject<JObject>(s);
var resultArr = (JArray)obj["results"];
foreach (JObject resultObj in resultArr)
{
var releaseDatesArr = (JArray)resultObj["release_dates"];
foreach (JObject releaseDateObj in releaseDatesArr)
{
_currentMPAARating = (string)releaseDateObj["certification"];
// ...
}
}
提琴:https://dotnetfiddle.net/SMzQTw
如果您只需要一项,这里是一个快捷方式。像这样将SelectToken
方法与递归下降运算符(..
)结合使用:
var obj = JsonConvert.DeserializeObject<JObject>(s);
_currentMPAARating = (string)obj.SelectToken("..certification");
提琴:https://dotnetfiddle.net/S1ScLO
但是请注意,上面只会返回第一个匹配项。如果您希望获得多个认证,则可以改用SelectTokens
(复数):
var obj = JsonConvert.DeserializeObject<JObject>(s);
var ratings = obj.SelectTokens("..certification").Select(t => (string)t).ToList();