Unity JSON Serializer not allowing for calling JSON Fields n JSON Objects - json

The have an issue where I am unable to call nested JSON Objects from a scraped website. The scraping process works prefectly, but the JSON Serializing part is the only issue. My code is shown below:
private void GetHtmlAsync()
{
var url = "https://opentdb.com/api.php?amount=10";
var httpClient = new HttpClient();
var html = httpClient.GetStringAsync(url);
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(MyDetail));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(html.Result));
stream.Position = 0;
MyDetail dataContractDetail = (MyDetail) jsonSerializer.ReadObject(stream);
text.text = "" + dataContractDetail.results[1];
//text.text = string.Concat("Test: ", dataContractDetail.question, " " + dataContractDetail.correct_answer);
}
public class MyDetail
{
[DataMember]
public Dictionary<string, questions> results
{
get;
set;
}
public class questions
{
public string question { get; set; }
public string correct_answer { get; set; }
}
[DataMember]
public string response_code
{
get;
set;
}
}
This code is the code that does not work, in that I try to call the first object in results by doing "results[1]", which returns an error after I attach, say, "question" to it by doing "results[1].question". This syntax seems reasonable, so I don;t understand why it is not working. My JSON File is shown below:
{
"response_code": 0,
"results": [
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "What is the name of the virus in "Metal Gear Solid 1"?",
"correct_answer": "FOXDIE",
"incorrect_answers": [
"FOXENGINE",
"FOXALIVE",
"FOXKILL"
]
},
{
"category": "Geography",
"type": "multiple",
"difficulty": "easy",
"question": "What is the official language of Costa Rica?",
"correct_answer": "Spanish",
"incorrect_answers": [
"English",
"Portuguese",
"Creole"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In Fallout 4, which type of power armor is first encountered in the early mission "When Freedom Calls" in a crashed Vertibird?",
"correct_answer": "T-45",
"incorrect_answers": [
"T-51",
"T-60",
"X-01"
]
},
{
"category": "Politics",
"type": "boolean",
"difficulty": "medium",
"question": "George W. Bush lost the popular vote in the 2004 United States presidential election.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In "Halo 2", what is the name of the monitor of Installation 05?",
"correct_answer": "2401 Penitent Tangent",
"incorrect_answers": [
"343 Guilty Spark",
"031 Exuberant Witness",
"252 Biodis Expolsion"
]
},
{
"category": "Entertainment: Books",
"type": "multiple",
"difficulty": "medium",
"question": "The book "Fahrenheit 451" was written by whom?",
"correct_answer": "Ray Bradbury",
"incorrect_answers": [
"R. L. Stine",
"Wolfgang Amadeus Mozart",
"Stephen King"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "multiple",
"difficulty": "hard",
"question": "In "Rick and Morty", from which dimension do Rick and Morty originate from?",
"correct_answer": "C-137",
"incorrect_answers": [
"J1977",
"C-136",
"C500-a"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "hard",
"question": "In which game did the character "Mario" make his first appearance?",
"correct_answer": "Donkey Kong",
"incorrect_answers": [
"Super Mario Bros.",
"Super Mario Land",
"Mario Bros."
]
},
{
"category": "Entertainment: Film",
"type": "multiple",
"difficulty": "hard",
"question": "What was Humphrey Bogart's middle name?",
"correct_answer": "DeForest",
"incorrect_answers": [
"DeWinter",
"Steven",
"Bryce"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "boolean",
"difficulty": "medium",
"question": "In "Avatar: The Last Airbender" and "The Legend of Korra", Lavabending is a specialized bending technique of Firebending.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
}
]
}

There are many issues in your code. I don't know all the libraries you are using but here is how I would do it.
First of all you start a GetStringAsync but you continue immediately without waiting for results. I don't know all the libraries you are using ofcourse maybe it is supposed to be like that?
However I would rather use Unity's UnityWebRequest.Get
private void GetHtmlAsync()
{
StartCoroutine(DownloadJson());
}
private IEnumerator DownloadJson()
{
var url = "https://opentdb.com/api.php?amount=10";
using(var uwr = UnityWebRequest.Get(url))
{
// send the request and wait for result
yield return uwr.SendWebRequest();
// Check for success!
if(uwr.isNetworkError || uwr.isHttpError || !string.IsNullOrWhiteSpace(uwr.error))
{
Debug.LogError($"Download failed with {uwr.responseCode} reason: {uwr.error}", this);
yield break;
}
var json = uwr.DownloadHandler.text;
// ... se below
}
}
Again I don't know your JSON library but your class seems not to match the JSON data structure which would be (by simply jamming it through json2csharp)
[Serializable]
public class Result
{
public string category;
public string type;
public string difficulty;
public string question;
public string correct_answer;
public List<string> incorrect_answers;
}
[Serializable]
public class MyDetail
{
public int response_code;
public List<Result> results;
}
for Unity I would use [Serializable] and also remove all the {get;set} in order to not use properties but fields.
Then you could simply use Unity's JsonUtility
...
MyDetail dataContractDetail = JsonUtility.FromJson<MyDetail>(json);
Then as mentioned in the comments note that array indices in c# are 0-based so the first element would be
var firstResult = dataContractDetail.results[0];
Now the question is what do you want to see on your text? The firstResult is no string but rather a class having various members! You could e.g. want to display the question like
text.text = firstResult.question;

Related

How to grab ratings array into in json

Hello StackOverflow users:
I'm tweaking a website that uses the omdb api to search for movies and I'm new to using json and Ajax. The website uses the knockout js framework. My question is: How do you setup an knockout observable command line that collects a json setting that seems like an array of info. I'm trying to grab the Ratings section of this json (The section is highlighted in bold)
{
"Title": "Batman Begins",
"Year": "2005",
"Rated": "PG-13",
"Released": "15 Jun 2005",
"Runtime": "140 min",
"Genre": "Action, Adventure, Thriller",
"Director": "Christopher Nolan",
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
"Language": "English, Urdu, Mandarin",
"Country": "USA, UK",
"Awards": "Nominated for 1 Oscar. Another 14 wins & 71 nominations.",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BYzc4ODgyZmYtMGFkZC00NGQyLWJiMDItMmFmNjJiZjcxYzVmXkEyXkFqcGdeQXVyNDYyMDk5MTU#._V1_SX300.jpg",
**"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "8.3/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "84%"
},
{
"Source": "Metacritic",
"Value": "70/100"
}
],**
"Metascore": "70",
"imdbRating": "8.3",
"imdbVotes": "1,099,197",
"imdbID": "tt0372784",
"Type": "movie",
"DVD": "18 Oct 2005",
"BoxOffice": "$204,100,000",
"Production": "Warner Bros. Pictures",
"Website": "http://www.batmanbegins.com/",
"Response": "True"
}
These are the ko settings used to grab the data:
self.currentMovie = {
Type: ko.observable(),
Year: ko.observable(),
Genre: ko.observable(),
Released: ko.observable(),
Runtime: ko.observable(),
Poster: ko.observable(),
Rated: ko.observable(),
imdbRating: ko.observable(),
imdbVotes: ko.observable(),
Ratings:ko.observable().Source = "Rotten Tomatoes",
Actors: ko.observable(),
Plot: ko.observable(),
Writer: ko.observable(),
Director: ko.observable(),
Country: ko.observable(),
Language: ko.observable(),
Title: ko.observable()
};
My first impulse was to setup the observable like this:
Ratings:ko.observable().Source = "Rotten Tomatoes",
But all that did was list the info verbatim and not the rest of the info. Should I use ko.observableArray or Is there another setting I could use?
To start with, if the API is providing info as an array, you should use an Observable Array. Next, you say you want to filter the array to get only the object with the Rotten Tomatoes score, and access the 'Value' as an observable. Correct?
Knockout provides utility functions (read more here), including one for filtering arrays called ko.utils.arrayFilter. So you could do this:
self.currentMovie = {
....
RatingsArray: ko.observableArray(),
....
}
var ratingFilterFunction = function (obArray) {
var trimmedArray = ko.utils.arrayFilter(obArray(), function (item) {
return item["Source"] === 'Rotten Tomatoes';
});
return ko.observable(trimmedArray[0]["Value"]);
};
self.CurrentMovie.Ratings = ratingFilterFunction(self.CurrentMovie.RatingsArray);
function vm(){
var self = this;
var allList = {
"Title": "Batman Begins",
"Year": "2005",
"Rated": "PG-13",
"Released": "15 Jun 2005",
"Runtime": "140 min",
"Genre": "Action, Adventure, Thriller",
"Director": "Christopher Nolan",
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
"Language": "English, Urdu, Mandarin",
"Country": "USA, UK",
"Awards": "Nominated for 1 Oscar. Another 14 wins & 71 nominations.",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BYzc4ODgyZmYtMGFkZC00NGQyLWJiMDItMmFmNjJiZjcxYzVmXkEyXkFqcGdeQXVyNDYyMDk5MTU#._V1_SX300.jpg",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "8.3/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "84%"
},
{
"Source": "Metacritic",
"Value": "70/100"
}
],
"Metascore": "70",
"imdbRating": "8.3",
"imdbVotes": "1,099,197",
"imdbID": "tt0372784",
"Type": "movie",
"DVD": "18 Oct 2005",
"BoxOffice": "$204,100,000",
"Production": "Warner Bros. Pictures",
"Website": "http://www.batmanbegins.com/",
"Response": "True"
}
self.Rating = ko.observable(allList.Ratings.find(o => o.Source === 'Rotten Tomatoes'));
}
// Activates knockout.js
ko.applyBindings(new vm());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<!-- This is a *view* - HTML markup that defines the appearance of your UI -->
<div data-bind="text: Rating().Value">
</div>
Lets say you received your JSON via ajax call into allList Object. You can get your Ratings array through allList.Ratings on which you can get the source you are looking for.
You can probably do
self.Rating = ko.observable(allList.Ratings.find(o => o.Source === 'Rotten Tomatoes'));
Assuming you have your required Ratings JSON in moviesRatingJson object
I am not using knockout.js, but I was trying to do the same thing in a C# forms apps. The solution was to create a simple class that defines a rating...
internal class Rating
{
public string Source { get; set; }
public string Value { get; set; }
}
...then create an array property, of that type, in the class that is passed to the JSON deserializer
internal class ImdbData
{
public string Title { get; set; }
public string Year { get; set; }
public string Rated { get; set; }
//...
public Rating[] Ratings { get; set; } // <-- ratings!
public string Metascore { get; set; }
public string imdbRating { get; set; }
//...
}
You will then be able to access the ratings like this
imdbDataObject.Ratings[0].Source
"Internet Movie Database"
imdbDataObject.Ratings[0].Value
"8.4/10"
imdbDataObject.Ratings[1].Source
"Rotten Tomatoes"
imdbDataObject.Ratings[1].Value
"97%"
imdbDataObject.Ratings[2].Source
"Metacritic"
imdbDataObject.Ratings[2].Value
"84/100"

Liferay API update Data with JSON

I am working on an API for my Portal, to provide users the ability to update there data via API directly from there internal Systems.
Liferay 6.2 bundle Tomcat. (for api call testing I use soapUI)
The get Methods work fine, (I have getAll, and getByID). getByID returns a JSON Object like this:
{
"ID": "ORGANIZATIONID",
"type": "ORGANIZATIONTYPE",
"name": "ORGANIZATIONNAME",
"URI": "ORGANIZATIONNAMEURI"
"date of inclusion": "INCLUTIONDATE",
"last activities": "LASTMODIFIEDDATE",
"address": {
"name of host institution": "NAMEOFHOSTINSTITUTE",
"street1": "STREET1",
"street2" : "STREET2",
"zip": "ZIP",
"city": "CITY",
"country": "COUNTRY",
},
"url": [{"ORGANIZATIONURL"}],
"main contact": {
"first name": "FIRSTNAME",
"last name" : "LASTNAME",
"phone": "PHONE",
"email": "MAINCONTACTEMAIL"
},
"type of host institution" : "TYPEOFHOSTINSTITUTE",
"diseases": [
{
"name": "DISEASENAME1",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
},
{
"name": "DISEASENAME2",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
}
]
}
I would like to have an API for Updating the diseases information for an organization. I have created a URL service where everything is in the url as parameters, but I would like to have it that the in the url only the id parameter is send and the rest of the information in a JSON object. Like:
/api/jsonws/....-portlet...../updateregbb/organization-id/16016/
and the data:
{
"ID": "ORGANIZATIONID",
"diseases": [
{
"name": "DISEASENAME1",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
},
{
"name": "DISEASENAME2",
"number": "SAMPLECOUNT",
"gene": "GENE",
"orphacode": "ORPHA"
"icd10": "ICD",
"omim": "OMIM";
"synonym": "SYNONYM"
}
]
}
But I could not find a solution how I can read the JSON data:
#JSONWebService(value = "updateregbb", method = "POST")
public void updateregbb2(long organizationId, Map jsondata) {
#JSONWebService(value = "updateregbb", method = "POST")
public void updateregbb(long organizationId, JSONObject json) {
How can I get the Data into my function?
Thanks for the help,
Best
Robert

Map json to dart objects

I'm looking for some direction on mapping json to an object. I'm trying to use live data from a web api. When I run the code I get the following error: Class '_LinkedHashMap' has no instance getter 'iterator'.
Here's what I'm trying to do:
import 'package:angular/angular.dart';
import 'dart:convert';
#NgController(
selector: '[movies]',
publishAs: 'ctrl'
)
class MoviesController {
// vars
bool moviesLoaded = false;
String nameToSearch = 'life';
Http _http;
List<MovieBrief> movies = [];
// constructor
MoviesController( Http this._http ) {
_loadData();
}
// functions
void _loadData() {
moviesLoaded = false;
// _http.get('http://www.omdbapi.com/?s=' + nameToSearch)
_http.get('movies_briefs.json')
.then((HttpResponse response) {
for (Map mb in response.data) {
movies.add(new MovieBrief.fromJsonMap(mb));
}
moviesLoaded = true;
},
onError: (Object obj) {
print(obj);
}
);
}
}
class MovieBrief {
String title;
String year;
String imdbId;
String type;
MovieBrief(this.title, this.year, this.imdbId, this.type);
String toJsonString() {
Map data = {"Search": [
{
"Title" : title,
"Year" : year,
"imdbID" : imdbId,
"Type" : type
}]};
return JSON.encode(data);
}
factory MovieBrief.fromJsonMap( Map json ) {
return new MovieBrief( json['Title'], json['Year'], json['imdbID'], json['Type']);
}
}
Here's a sample of the json results returned by the web api:
{
"Search": [
{
"Title": "Life of Pi",
"Year": "2012",
"imdbID": "tt0454876",
"Type": "movie"
},
{
"Title": "Life Is Beautiful",
"Year": "1997",
"imdbID": "tt0118799",
"Type": "movie"
},
{
"Title": "Life of Brian",
"Year": "1979",
"imdbID": "tt0079470",
"Type": "movie"
},
{
"Title": "It's a Wonderful Life",
"Year": "1946",
"imdbID": "tt0038650",
"Type": "movie"
},
{
"Title": "A Bug's Life",
"Year": "1998",
"imdbID": "tt0120623",
"Type": "movie"
},
{
"Title": "A Bug's Life",
"Year": "1998",
"imdbID": "tt0174716",
"Type": "movie"
},
{
"Title": "The Tree of Life",
"Year": "2011",
"imdbID": "tt0478304",
"Type": "movie"
},
{
"Title": "The Life Aquatic with Steve Zissou",
"Year": "2004",
"imdbID": "tt0362270",
"Type": "movie"
},
{
"Title": "Lara Croft Tomb Raider: The Cradle of Life",
"Year": "2003",
"imdbID": "tt0325703",
"Type": "movie"
},
{
"Title": "Dan in Real Life",
"Year": "2007",
"imdbID": "tt0480242",
"Type": "movie"
}
]
}
Have you looked at the json_object package? This parses a json string and creates properties on the resulting object, in your case you would have say film.title, film.year etc. You can store each json_object in a list.
I'm guessing response.data is a map, so you can't iterate on it with a for loop. You need to either use response.data.keys, response.data.values, or use the forEach method on the map, which provides both.
response.data.forEach((key, value) => movies.add(Etc)
As per the other response, something like json_object is also worth looking into, but that's a way of avoiding hard coding the field mappings.

VB & Rotten Tomatoes JSON API

I'm trying to allow a user to enter a film title into my program, then have the program return the top three matching films in the rotten tomatoes database.
Here's the code I have so far:
Private Sub Query(ByVal searchTerm As String)
'declare the url, request, response and reader,
Dim url As String
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
Console.BackgroundColor = ConsoleColor.Red : Console.WriteLine(" QUERYING ROTTEN TOMATOES FOR THE SEARCHTERM {0} ", searchTerm) : Console.BackgroundColor = ConsoleColor.Black
Try
'base url, query, apikey, page (or result) limit,
url = String.Format("http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={0}&apikey={1}&page_limit={2}", searchTerm, myApiKey, "3")
'make the request
request = DirectCast(WebRequest.Create(url), HttpWebRequest)
'get the response
response = DirectCast(request.GetResponse(), HttpWebResponse)
'read the response
reader = New StreamReader(response.GetResponseStream())
'declare a string for the raw response
Dim rawResponse As String
'get the response a raw string
rawResponse = reader.ReadToEnd()
'write the raw response to the console
Console.WriteLine(rawResponse)
'write that the rest of the data is specific
Console.BackgroundColor = ConsoleColor.Red : Console.WriteLine(" EXTRACTED DATA: ") : Console.BackgroundColor = ConsoleColor.Black
'parse the results from the rawresponse
Dim jResults As JObject = JObject.Parse(rawResponse)
Console.WriteLine(ParseTitle(jResults("total")))
Console.WriteLine(ParseTitle(jResults("title")))
'Console.WriteLine(ParseTitle(jResults("critics_score")))
Catch ex As Exception
Console.WriteLine("Error: " & ex.ToString)
Finally
If Not response Is Nothing Then response.Close()
End Try
Console.BackgroundColor = ConsoleColor.Red : Console.WriteLine(" QUERY FINISHED. PRESS ANY KEY TO CLOSE... ") : Console.BackgroundColor = ConsoleColor.Black
Console.ReadKey()
End Sub
I'm using the JSON.Net library, and, truthfully, have no experience with JSON - I've been working of off tutorials.
I'd like to be able to get all the films returned to an array of Movie data structures Can anyone help me out?
Here's the response I get if I search for 'toy story':
{
"total": 7,
"movies": [
{
"id": "770672122",
"title": "Toy Story 3",
"year": 2010,
"mpaa_rating": "G",
"runtime": 103,
"critics_consensus": "Deftlyblending comedy, adventure, and honest emotion, Toy Story 3 is a raresecond sequel that reallyworks.",
"release_dates": {
"theater": "2010-06-18",
"dvd": "2010-11-02"
},
"ratings": {
"critics_rating": "CertifiedFresh",
"critics_score": 99,
"audience_rating": "Upright",
"audience_score": 91
},
"synopsis": "Pixarreturns to their first success with Toy Story 3. The movie begins withAndy leaving for college and donating his beloved toys -- includingWoody (Tom Hanks) and Buzz (Tim Allen) -- to a daycare. While the crewmeets new friends, including Ken (Michael Keaton), they soon grow tohate their new surroundings and plan an escape. The film was directedby Lee Unkrich from a script co-authored by Little Miss Sunshinescribe Michael Arndt. ~ Perry Seibert,Rovi",
"posters": {
"thumbnail": "http://content6.flixster.com/movie/11/13/43/11134356_mob.jpg",
"profile": "http://content6.flixster.com/movie/11/13/43/11134356_pro.jpg",
"detailed": "http://content6.flixster.com/movie/11/13/43/11134356_det.jpg",
"original": "http://content6.flixster.com/movie/11/13/43/11134356_ori.jpg"
},
"abridged_cast": [
{
"name": "TomHanks",
"id": "162655641",
"characters": [
"Woody"
]
},
{
"name": "TimAllen",
"id": "162655909",
"characters": [
"Buzz Lightyear"
]
},
{
"name": "JoanCusack",
"id": "162655020",
"characters": [
"Jessie theCowgirl"
]
},
{
"name": "NedBeatty",
"id": "162672460",
"characters": [
"Lots-o'-Huggin'Bear",
"Lotso"
]
},
{
"name": "DonRickles",
"id": "341817905",
"characters": [
"Mr. PotatoHead"
]
}
],
"alternate_ids": {
"imdb": "0435761"
},
"links": {
"self": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122.json",
"alternate": "http://www.rottentomatoes.com/m/toy_story_3/",
"cast": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/cast.json",
"clips": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/clips.json",
"reviews": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/reviews.json",
"similar": "http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json"
}
},
{
"id": "9414",
"title": "ToyStory2",
"year": 1999,
"mpaa_rating": "G",
"runtime": 92,
"critics_consensus": "ToyStory 2 employs inventive storytelling, gorgeous animation, and a topnotch voice cast to deliver another rich moviegoing experience for allages, one that's arguably even better than itspredecessor.",
"release_dates": {
"theater": "1999-11-24",
"dvd": "2000-10-17"
},
"ratings": {
"critics_rating": "CertifiedFresh",
"critics_score": 100,
"audience_rating": "Upright",
"audience_score": 72
},
"synopsis": "",
"posters": {
"thumbnail": "http://content6.flixster.com/movie/10/93/63/10936392_mob.jpg",
"profile": "http://content6.flixster.com/movie/10/93/63/10936392_pro.jpg",
"detailed": "http://content6.flixster.com/movie/10/93/63/10936392_det.jpg",
"original": "http://content6.flixster.com/movie/10/93/63/10936392_ori.jpg"
},
"abridged_cast": [
{
"name": "TomHanks",
"id": "162655641",
"characters": [
"Woody"
]
},
{
"name": "TimAllen",
"id": "162655909",
"characters": [
"Buzz Lightyear"
]
},
{
"name": "JoanCusack",
"id": "162655020",
"characters": [
"Jessie theCowgirl"
]
},
{
"name": "KelseyGrammer",
"id": "162660300",
"characters": [
"Stinky Pete theProspector"
]
},
{
"name": "DonRickles",
"id": "341817905",
"characters": [
"Mr. PotatoHead"
]
}
],
"alternate_ids": {
"imdb": "0120363"
},
"links": {
"self": "http://api.rottentomatoes.com/api/public/v1.0/movies/9414.json",
"alternate": "http://www.rottentomatoes.com/m/toy_story_2/",
"cast": "http://api.rottentomatoes.com/api/public/v1.0/movies/9414/cast.json",
"clips": "http://api.rottentomatoes.com/api/public/v1.0/movies/9414/clips.json",
"reviews": "http://api.rottentomatoes.com/api/public/v1.0/movies/9414/reviews.json",
"similar": "http://api.rottentomatoes.com/api/public/v1.0/movies/9414/similar.json"
}
},
{
"id": "9559",
"title": "ToyStory",
"year": 1995,
"mpaa_rating": "G",
"runtime": 80,
"critics_consensus": "Asentertaining as it is innovative, Toy Story kicked off Pixar'sunprecedented run of quality pictures, reinvigorating animated film intheprocess.",
"release_dates": {
"theater": "1995-11-22",
"dvd": "2001-03-20"
},
"ratings": {
"critics_rating": "CertifiedFresh",
"critics_score": 100,
"audience_rating": "Upright",
"audience_score": 81
},
"synopsis": "",
"posters": {
"thumbnail": "http://content7.flixster.com/movie/10/93/63/10936393_mob.jpg",
"profile": "http://content7.flixster.com/movie/10/93/63/10936393_pro.jpg",
"detailed": "http://content7.flixster.com/movie/10/93/63/10936393_det.jpg",
"original": "http://content7.flixster.com/movie/10/93/63/10936393_ori.jpg"
},
"abridged_cast": [
{
"name": "TomHanks",
"id": "162655641",
"characters": [
"Woody"
]
},
{
"name": "TimAllen",
"id": "162655909",
"characters": [
"Buzz Lightyear"
]
},
{
"name": "DonRickles",
"id": "341817905",
"characters": [
"Mr. PotatoHead"
]
},
{
"name": "Jim Varney",
"id": "162662792",
"characters": [
"SlinkyDog"
]
},
{
"name": "WallaceShawn",
"id": "162671862",
"characters": [
"Rex"
]
}
],
"alternate_ids": {
"imdb": "0114709"
},
"links": {
"self": "http://api.rottentomatoes.com/api/public/v1.0/movies/9559.json",
"alternate": "http://www.rottentomatoes.com/m/toy_story/",
"cast": "http://api.rottentomatoes.com/api/public/v1.0/movies/9559/cast.json",
"clips": "http://api.rottentomatoes.com/api/public/v1.0/movies/9559/clips.json",
"reviews": "http://api.rottentomatoes.com/api/public/v1.0/movies/9559/reviews.json",
"similar": "http://api.rottentomatoes.com/api/public/v1.0/movies/9559/similar.json"
}
}
],
"links": {
"self": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=toy+story&page_limit=3&page=1",
"next": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=toy+story&page_limit=3&page=2"
},
"link_template": "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={search-term}&page_limit={results-per-page}&page={page-number}"
}
First you need to create classes to receive the JSON data:
Public Class ReleaseDates
Public Property theater As String
Public Property dvd As String
End Class
Public Class Ratings
Public Property critics_rating As String
Public Property critics_score As Integer
Public Property audience_rating As String
Public Property audience_score As Integer
End Class
Public Class Posters
Public Property thumbnail As String
Public Property profile As String
Public Property detailed As String
Public Property original As String
End Class
Public Class AbridgedCast
Public Property name As String
Public Property id As String
Public Property characters As List(Of String)
End Class
Public Class AlternateIds
Public Property imdb As String
End Class
Public Class Links
Public Property self As String
Public Property alternate As String
Public Property cast As String
Public Property clips As String
Public Property reviews As String
Public Property similar As String
End Class
Public Class Movie
Public Property id As String
Public Property title As String
Public Property year As Integer
Public Property mpaa_rating As String
Public Property runtime As Integer
Public Property critics_consensus As String
Public Property release_dates As ReleaseDates
Public Property ratings As Ratings
Public Property synopsis As String
Public Property posters As Posters
Public Property abridged_cast As List(Of AbridgedCast)
Public Property alternate_ids As AlternateIds
Public Property links As Links
End Class
Public Class Links2
Public Property self As String
<JsonProperty(PropertyName:="next")>
Public Property nextItem As String
End Class
Public Class RootObject
Public Property total As Integer
Public Property movies As List(Of Movie)
Public Property links As Links2
Public Property link_template As String
End Class
Once you have done that, you can simply call JsonConvert.DeserializeObject to deserialize your JSON data:
Sub Main()
Dim json As String
json = "{""total"":7,""movies"":[{""id"":""770672122"",""title"":""Toy Story 3"",""year"":2010,""mpaa_rating"":""G"",""runtime"":103,""critics_consensus"":""Deftly blending comedy, adventure, and honest emotion, Toy Story 3 is a rare second sequel that really works."",""release_dates"":{""theater"":""2010-06-18"",""dvd"":""2010-11-02""},""ratings"":{""critics_rating"":""Certified Fresh"",""critics_score"":99,""audience_rating"":""Upright"",""audience_score"":91},""synopsis"":""Pixar returns to their first success with Toy Story 3. The movie begins with Andy leaving for college and donating his beloved toys -- including Woody (Tom Hanks) and Buzz (Tim Allen) -- to a daycare. While the crew meets new friends, including Ken (Michael Keaton), they soon grow to hate their new surroundings and plan an escape. The film was directed by Lee Unkrich from a script co-authored by Little Miss Sunshine scribe Michael Arndt. ~ Perry Seibert, Rovi"",""posters"":{""thumbnail"":""http://content6.flixster.com/movie/11/13/43/11134356_mob.jpg"",""profile"":""http://content6.flixster.com/movie/11/13/43/11134356_pro.jpg"",""detailed"":""http://content6.flixster.com/movie/11/13/43/11134356_det.jpg"",""original"":""http://content6.flixster.com/movie/11/13/43/11134356_ori.jpg""},""abridged_cast"":[{""name"":""Tom Hanks"",""id"":""162655641"",""characters"":[""Woody""]},{""name"":""Tim Allen"",""id"":""162655909"",""characters"":[""Buzz Lightyear""]},{""name"":""Joan Cusack"",""id"":""162655020"",""characters"":[""Jessie the Cowgirl""]},{""name"":""Ned Beatty"",""id"":""162672460"",""characters"":[""Lots-o'-Huggin' Bear"",""Lotso""]},{""name"":""Don Rickles"",""id"":""341817905"",""characters"":[""Mr. Potato Head""]}],""alternate_ids"":{""imdb"":""0435761""},""links"":{""self"":""http://api.rottentomatoes.com/api/public/v1.0/movies/770672122.json"",""alternate"":""http://www.rottentomatoes.com/m/toy_story_3/"",""cast"":""http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/cast.json"",""clips"":""http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/clips.json"",""reviews"":""http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/reviews.json"",""similar"":""http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json""}},{""id"":""9414"",""title"":""Toy Story 2"",""year"":1999,""mpaa_rating"":""G"",""runtime"":92,""critics_consensus"":""Toy Story 2 employs inventive storytelling, gorgeous animation, and a top notch voice cast to deliver another rich moviegoing experience for all ages, one that's arguably even better than its predecessor."",""release_dates"":{""theater"":""1999-11-24"",""dvd"":""2000-10-17""},""ratings"":{""critics_rating"":""Certified Fresh"",""critics_score"":100,""audience_rating"":""Upright"",""audience_score"":72},""synopsis"":"""",""posters"":{""thumbnail"":""http://content6.flixster.com/movie/10/93/63/10936392_mob.jpg"",""profile"":""http://content6.flixster.com/movie/10/93/63/10936392_pro.jpg"",""detailed"":""http://content6.flixster.com/movie/10/93/63/10936392_det.jpg"",""original"":""http://content6.flixster.com/movie/10/93/63/10936392_ori.jpg""},""abridged_cast"":[{""name"":""Tom Hanks"",""id"":""162655641"",""characters"":[""Woody""]},{""name"":""Tim Allen"",""id"":""162655909"",""characters"":[""Buzz Lightyear""]},{""name"":""Joan Cusack"",""id"":""162655020"",""characters"":[""Jessie the Cowgirl""]},{""name"":""Kelsey Grammer"",""id"":""162660300"",""characters"":[""Stinky Pete the Prospector""]},{""name"":""Don Rickles"",""id"":""341817905"",""characters"":[""Mr. Potato Head""]}],""alternate_ids"":{""imdb"":""0120363""},""links"":{""self"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9414.json"",""alternate"":""http://www.rottentomatoes.com/m/toy_story_2/"",""cast"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9414/cast.json"",""clips"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9414/clips.json"",""reviews"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9414/reviews.json"",""similar"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9414/similar.json""}},{""id"":""9559"",""title"":""Toy Story"",""year"":1995,""mpaa_rating"":""G"",""runtime"":80,""critics_consensus"":""As entertaining as it is innovative, Toy Story kicked off Pixar's unprecedented run of quality pictures, reinvigorating animated film in the process."",""release_dates"":{""theater"":""1995-11-22"",""dvd"":""2001-03-20""},""ratings"":{""critics_rating"":""Certified Fresh"",""critics_score"":100,""audience_rating"":""Upright"",""audience_score"":81},""synopsis"":"""",""posters"":{""thumbnail"":""http://content7.flixster.com/movie/10/93/63/10936393_mob.jpg"",""profile"":""http://content7.flixster.com/movie/10/93/63/10936393_pro.jpg"",""detailed"":""http://content7.flixster.com/movie/10/93/63/10936393_det.jpg"",""original"":""http://content7.flixster.com/movie/10/93/63/10936393_ori.jpg""},""abridged_cast"":[{""name"":""Tom Hanks"",""id"":""162655641"",""characters"":[""Woody""]},{""name"":""Tim Allen"",""id"":""162655909"",""characters"":[""Buzz Lightyear""]},{""name"":""Don Rickles"",""id"":""341817905"",""characters"":[""Mr. Potato Head""]},{""name"":""Jim Varney"",""id"":""162662792"",""characters"":[""Slinky Dog""]},{""name"":""Wallace Shawn"",""id"":""162671862"",""characters"":[""Rex""]}],""alternate_ids"":{""imdb"":""0114709""},""links"":{""self"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9559.json"",""alternate"":""http://www.rottentomatoes.com/m/toy_story/"",""cast"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9559/cast.json"",""clips"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9559/clips.json"",""reviews"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9559/reviews.json"",""similar"":""http://api.rottentomatoes.com/api/public/v1.0/movies/9559/similar.json""}}],""links"":{""self"":""http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=toy+story&page_limit=3&page=1"",""next"":""http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=toy+story&page_limit=3&page=2""},""link_template"":""http://api.rottentomatoes.com/api/public/v1.0/movies.json?q={search-term}&page_limit={results-per-page}&page={page-number}""}"
Dim obj As RootObject
obj = JsonConvert.DeserializeObject(Of RootObject)(json)
End Sub

parsing json with high level "unknown" names

How do you parse a JSON structure such as this
"properties": {
"/base/pinball/pinball_machine_basis/pinball_machines": {
"expected_type": {
"id": "/base/pinball/pinball_machine",
"text": "Pinball Machine"
},
"text": "Pinball Machines",
"values": [
{
"id": "/m/026z8cp",
"text": "The Lord of the Rings",
"url": "http://www.freebase.com/view/m/026z8cp"
}
]
},
"/common/topic/article": {
"expected_type": {
"id": "/common/document",
"text": "Document"
},
"text": "article",
"values": [
{
"id": "/m/025h5z",
"text": "",
"url": "http://www.freebase.com/view/m/025h5z"
}
]
},
"/common/topic/image": {
"expected_type": {
"id": "/common/image",
"text": "Image"
},
"text": "image",
"values": [
{
"id": "/m/029wvk4",
"text": "The Lord of the Rings: The Motion Picture Trilogy poster (2003)",
"url": "http://www.freebase.com/view/m/029wvk4"
},
{
"id": "/m/0bdyf3j",
"text": "",
"url": "http://www.freebase.com/view/m/0bdyf3j"
},
{
"id": "/m/0glyg_4",
"text": "lotr-extended-blu-ray.jpg",
"url": "http://www.freebase.com/view/m/0glyg_4"
}
]
},
I will not know in advance the high level names such as "/base/pinball/pinball_machine_basis/pinball_machines", "/common/topic/article", or "/exhibitions/exhibition_subject/exhibitions_created_about_this_subject"
i have tried Jackson but cannot see how to generate a java class that matches this structure. it apears to be an array but isnt surrounded with "[" or "]".
the structure repeats "expected_type", "text", "values" etc. what am i missing?
Having hit a brick wall with this problem i contacted Tatu Saloranta
who was extremely helpful. with his help i managed to complete my Freebase Explorer Android Application. I have made my android application source code available in GITHUB if anyone is interested.
GITHUB source Code
The android application is also available here
Well. I have the same problem. But your answer is not very helpful for me. I am sure you created a great app and I am happy for you that you could solve the problem. But I have no time to dig through your source code on GitHub. I would really appreciate if you could just post the code snippet which solves the problem. Many Thanks.
After some research I found this solution here with #JsonAnySetter:
private Map<String, Object> all = new HashMap<String, Object>();
#JsonAnySetter
public void set(String name, Object value) {
all.put(name, value);
}
public Map<String, Object> getAll() {
return all;
}
public void setAll(Map<String, Object> all) {
this.all = all;
}
With this Annotation you can handle any kind of unknown properties in a JSON stream. That worked for me.