On this line of code:
var arr = JsonConvert.DeserializeObject<JArray>(s);
...I am getting, "Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Newtonsoft.Json.Linq.JArray'."
I changed that line to this:
JArray arr = JsonConvert.DeserializeObject<JArray>(s);
...and got the same err msg.
I changed it to this:
var arr = JsonConvert.DeserializeObject<JObject>(s);
...and it wouldn't even compile.
The value of what has been read by the call (in string s) at this point is:
{"id":347745,"results":[{"iso_3166_1":"US","release_dates":[{"certification":"","iso_639_1":"","note":"","release_date":"1936-12-12T00:00:00.000Z","type":3}]}]}
All I want from it is the value for "certification"; In this case, the certification value is an empty string ("certification":"")
In context, the code is:
. . .
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);
}
Your JSON is not an array, it is an object which contains an array (results
). But it's actually more complicated than that: the certification
string you seek is nested even further down inside a second release_dates
array.
If you take your JSON and reformat it using a JSON validator/beautifier, it should become more clear:
{
"id": 347745,
"results": [
{
"iso_3166_1": "US",
"release_dates": [
{
"certification": "",
"iso_639_1": "",
"note": "",
"release_date": "1936-12-12T00:00:00Z",
"type": 3
}
]
}
]
}
So to get the data you are looking for using regular foreach
loops, you would need code like this:
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"];
// ...
}
}
Fiddle: https://dotnetfiddle.net/SMzQTw
If all you need is the one item, here's a shortcut. Use the SelectToken
method with the recursive descent operator (..
) like this:
var obj = JsonConvert.DeserializeObject<JObject>(s);
_currentMPAARating = (string)obj.SelectToken("..certification");
Fiddle: https://dotnetfiddle.net/S1ScLO
But note the above will only return the first match. If you are expecting multiple certifications, you can use SelectTokens
(plural) instead:
var obj = JsonConvert.DeserializeObject<JObject>(s);
var ratings = obj.SelectTokens("..certification").Select(t => (string)t).ToList();
Fiddle: https://dotnetfiddle.net/zyjNnJ