This is the JSON - GitHub Gist Below is the code which is not working. Code (CSharp): using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class MovieNetworking : MonoBehaviour { string json; void Start() { var url = "https://gist.githubusercontent.com/knightcube/580d0f94242cbd1fe349cded215dec00/raw/5ab4e39a148e16661d0938befac13ce3174f91cc/Movie.json"; //StartCoroutine(GetRequest(Utils.TRENDING_URL)); StartCoroutine(GetRequest(url)); } private class Movie { public int id; public bool video; public string title; public int vote_count { get; set; } public double vote_average { get; set; } public string release_date { get; set; } public string original_language { get; set; } public string original_title { get; set; } public IList<int> genre_ids { get; set; } public string backdrop_path { get; set; } public bool adult { get; set; } public string overview { get; set; } public string poster_path { get; set; } public double popularity { get; set; } public string media_type { get; set; } //public static Movie CreateFromJson(string jsonString) //{ // return JsonUtility.FromJson<Movie>(jsonString); //} } private class Movies { public int page { get; set; } public IList<Movie> results { get; set; } public int total_pages { get; set; } public int total_results { get; set; } public static Movies CreateFromJson(string jsonString) { return JsonUtility.FromJson<Movies>(jsonString); } } private void MovieJsonParser(string json) { Debug.Log(json); Movies jsonObject = Movies.CreateFromJson(json); Debug.Log(jsonObject.ToString()); int count = jsonObject.page; Debug.Log(count); } IEnumerator GetRequest(string uri) { using (UnityWebRequest webRequest = UnityWebRequest.Get(uri)) { // Request and wait for the desired page. yield return webRequest.SendWebRequest(); string[] pages = uri.Split('/'); int page = pages.Length - 1; if (webRequest.isNetworkError) { Debug.Log(pages[page] + ": Error: " + webRequest.error); } else { Debug.Log(pages[page] + ":\nReceived: "); } json = webRequest.downloadHandler.text; MovieJsonParser(json); } } } Where am I going wrong?
You cannot parse JSON fields into C# properties, because they're technically methods. If you change your properties into fields, the JSON should parse correctly.
I tried that but it didn't work. Can you try attaching the script to some GameObject in your scene and check? Do I need to have public setters and getters for all my private fields, even though I am accessing just one of those?
The class may have to be public, but the class certainly has to be decorated with this attribute: https://docs.microsoft.com/en-us/dotnet/api/system.serializableattribute?view=netcore-3.1 Otherwise it will not ... serialize! Many other full JSON packages (such as JSON .NET, free on the asset store) will actually handle the properties just like the fields, but I Unity's "tiny JSON" does not. Here's LitJSON for comparison: Code (csharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class garg : MonoBehaviour { [System.Serializable] public class Testing { public int AField; public int AProperty { get; set; } } void Start () { var t = new Testing(); t.AField = 123; t.AProperty = 345; var s1 = JsonUtility.ToJson(t); Debug.Log( "Unity JSON:" + s1); var s2 = LitJson.Json.serialize(t); Debug.Log( "LitJSON:" + s2); } } And the output: Addendum: the class CAN be private and it will serialize the same way as above.
I made the class public, added the Serializable attribute, used the JSON .Net Unity asset, converted the properties to fields and it worked. Here is the updated code - Code (CSharp): using System; using System.Collections; using System.Collections.Generic; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Networking; public class MovieNetworking : MonoBehaviour { string json; void Start() { var url = "https://gist.githubusercontent.com/knightcube/580d0f94242cbd1fe349cded215dec00/raw/848fa4a01f2363cd82310738f26a633e4ea0285b/Movie.json"; // StartCoroutine(GetRequest(Utils.TRENDING_URL)); StartCoroutine(GetRequest(url)); } [Serializable] public class Movie { public int id; public bool video; public string title; public int vote_count; public double vote_average; public string release_date; public string original_language; public string original_title; public int[] genre_ids; public string backdrop_path; public bool adult; public string overview; public string poster_path; public double popularity; public string media_type; //public static Movie CreateFromJson(string jsonString) //{ // return JsonUtility.FromJson<Movie>(jsonString); //} } [Serializable] public class Movies { public int page; public Movie[] results; public int total_pages; public int total_results; public Movies() { } public static Movies CreateFromJson(string jsonString) { return JsonConvert.DeserializeObject<Movies>(jsonString); //return JsonUtility.FromJson<Movies>(jsonString); } public Movie[] GetMovies(){ return results; } } private void MovieJsonParser(string json) { Debug.Log(json); Movies jsonObject = Movies.CreateFromJson(json); Debug.Log(jsonObject.ToString()); int count = jsonObject.GetMovies().Length; foreach(Movie movie in jsonObject.GetMovies()) { Debug.Log(movie.title); } } IEnumerator GetRequest(string uri) { using (UnityWebRequest webRequest = UnityWebRequest.Get(uri)) { // Request and wait for the desired page. yield return webRequest.SendWebRequest(); string[] pages = uri.Split('/'); int page = pages.Length - 1; if (webRequest.isNetworkError) { Debug.Log(pages[page] + ": Error: " + webRequest.error); } else { Debug.Log(pages[page] + ":\nReceived: "); } json = webRequest.downloadHandler.text; MovieJsonParser(json); } } } I think making those fields public is not a good practice. Is it? If not then how can I keep those encapsulated?
You can make the fields private and add the [SerializeField] attribute onto each one: Code (CSharp): [Serializable] public class Movie { [SerializeField] private int id; [SerializeField] private bool video; [SerializeField] private string title; [SerializeField] private int vote_count; [SerializeField] private double vote_average; [SerializeField] private string release_date; [SerializeField] private string original_language; [SerializeField] private string original_title; [SerializeField] private int[] genre_ids; [SerializeField] private string backdrop_path; [SerializeField] private bool adult; [SerializeField] private string overview; [SerializeField] private string poster_path; [SerializeField] private double popularity; [SerializeField] private string media_type; //public static Movie CreateFromJson(string jsonString) //{ // return JsonUtility.FromJson<Movie>(jsonString); //} } Code (CSharp): [Serializable] public class Movies { [SerializeField] private int page; [SerializeField] private Movie[] results; [SerializeField] private int total_pages; [SerializeField] private int total_results; public Movies() { } public static Movies CreateFromJson(string jsonString) { return JsonConvert.DeserializeObject<Movies>(jsonString); //return JsonUtility.FromJson<Movies>(jsonString); } public Movie[] GetMovies(){ return results; } }