Home > Enterprise >  C# - Deserialize JSON into an Object, and then run a foreach loop to add into a listview
C# - Deserialize JSON into an Object, and then run a foreach loop to add into a listview

Time:10-30

I've been struggling to deserialize an JSON request return from the IGDB API that I'm using for my application. I've managed to deserialize successfully in another part of my project, however this JSON has multiple values which I'm not sure how to correctly convert into object members. I'm constantly receiving System.Text.Json exceptions.

My GameListObject class is set as:

 public class GameListObject
    {
        [JsonPropertyName("id")]
        public string GameID { get; set; }
        [JsonPropertyName("name")]
        public string GameName { get; set; }
        [JsonPropertyName("release_dates")]
        public string ReleaseDate { get; set; }
    }

Try statement for API request and return:

//On search box content change
    private async void gamehub_search_TextChanged(object sender, TextChangedEventArgs e)
    {
        ObservableCollection<GameListObject> dataList = new ObservableCollection<GameListObject>();
        gamehub_list.ItemsSource = dataList;
        dataList.Clear();

        var SearchQuery = gamehub_search.Text;

        try
        {
            // Construct the HttpClient and Uri
            HttpClient httpClient = new HttpClient();
            Uri uri = new Uri("https://api.igdb.com/v4/games");

            httpClient.DefaultRequestHeaders.Add("Client-ID", App.GlobalClientidIGDB);
            httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer "   App.GlobalAccessIGDB);
            //Debug.WriteLine("Request Headers: ");

            // Construct the JSON to post
            HttpStringContent content = new HttpStringContent($"search \"{SearchQuery}\"; fields name,release_dates.human;");
            Debug.WriteLine("Request Contents: "   content);

            // Post the JSON and wait for a response
            HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
                uri,
                content);

            // Make sure the post succeeded, and write out the response
            httpResponseMessage.EnsureSuccessStatusCode();
            var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
            Debug.WriteLine("Request Response: "   httpResponseBody);

            //Deserialise the return output into game id, game name and release date
            GameListObject gamelistobject = JsonSerializer.Deserialize<GameListObject>(httpResponseBody);


            foreach (GameListObject GameListObject in gamelistobject) //Receiving error under 'gamelistobject'
            {
                //Add new item to the ListView
                GameListObject newitem = new GameListObject() { GameID = gamelistobject.GameID, GameName = gamelistobject.GameName, ReleaseDate = gamelistobject.ReleaseDate };
                dataList.Add(newitem);
            }

            Debug.WriteLine($"id: {gamelistobject.GameID}");
            Debug.WriteLine($"name: {gamelistobject.GameName}");
            Debug.WriteLine($"release_dates: {gamelistobject.ReleaseDate}");
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }

Note: Receiving error within the Foreach statement: Under 'gamelistobject' stating "foreach statement cannot operate on variables of type 'GameHubs.GameListObject' because it does not contain public instance or extension definition for 'GetEnumerator'

An example of a return JSON statement from the API:

{
    "id": 277,
    "name": "Battlefield 2",
    "release_dates": [
      {
        "id": 52086,
        "human": "Jun 21, 2005"
      },
      {
        "id": 52087,
        "human": "Jun 22, 2005"
      },
      {
        "id": 52088,
        "human": "Jun 24, 2005"
      }
    ]
  },
  {
    "id": 89571,
    "name": "Battlefield V: Deluxe Edition",
    "release_dates": [
      {
        "id": 157810,
        "human": "Nov 16, 2018"
      },
      {
        "id": 157811,
        "human": "Nov 16, 2018"
      },
      {
        "id": 157812,
        "human": "Nov 16, 2018"
      }
    ]
  }

CodePudding user response:

try to use List instead of GameListObject, and you dont need foreach loop in this case

//Deserialise the return output into game id, game name and release date
   List<GameListObject> gamelistobjects = JsonSerializer.Deserialize<List<GameListObject>>(httpResponseBody);


   ObservableCollection<GameListObject> dataList = 
new ObservableCollection<GameListObject>(gamelistobjects);

or even one line would be ok

 ObservableCollection<GameListObject> dataList = JsonConvert.DeserializeObject<ObservableCollection<GameListObject>>(json);

test


foreach (var item in dataList)
    {
        Debug.WriteLine($"id: {item.GameID}");
        Debug.WriteLine($"name: {item.GameName}");

         if(item.ReleaseDates!=null)
        foreach (var date in item.ReleaseDates)
        {
            Debug.WriteLine($"releaseDate: {date.Human}");
        }
    }

output

d: 277
name: Battlefield 2
releaseDate: Jun 21, 2005
releaseDate: Jun 22, 2005
releaseDate: Jun 24, 2005
id: 89571
name: Battlefield V: Deluxe Edition
releaseDate: Nov 16, 2018
releaseDate: Nov 16, 2018
releaseDate: Nov 16, 2018

and try this clasess

public partial class GameListObject
    {
    [JsonProperty("id")]
    public long GameID { get; set; }

    [JsonProperty("name")]
    public string GameName { get; set; }

    [JsonProperty("release_dates")]
    public ObservableCollection<ReleaseDate> ReleaseDates { get; set; }
}

public partial class ReleaseDate
{
    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("human")]
    public string Human { get; set; }
}

public partial class ReleaseDate
{
    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("human")]
    public string Human { get; set; }
}
  • Related