You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用IGDB API时JSON反序列化失败及ListView遍历加载报错问题求助

Let's break down the issues you're facing and fix them step by step:

1. Core Problems Identified

  • API returns an array, not a single object: Your current code tries to deserialize the response into one GameListObject, but IGDB sends back a JSON array of game entries. That's why your foreach loop throws an error—you can't iterate over a single object.
  • release_dates is an array, not a string: Your GameListObject defines ReleaseDate as a string, but the API returns a collection of release date objects (each with an id and human-readable date). Your model doesn't match this structure.
  • Request content type mismatch: IGDB expects plain text for its query language, not JSON—this might be causing silent parsing issues too.

2. Step-by-Step Fixes

Step 1: Update Your Model Classes

First, create a class to represent individual release date entries, then adjust GameListObject to match the API's structure:

// Class to map each release date entry from the API
public class ReleaseDateItem
{
    [JsonPropertyName("id")]
    public int Id { get; set; }
    
    [JsonPropertyName("human")]
    public string HumanReadableDate { get; set; }
}

// Updated GameListObject with correct property types
public class GameListObject
{ 
    [JsonPropertyName("id")] 
    public int GameID { get; set; } // Changed to int (IGDB returns IDs as integers)
    
    [JsonPropertyName("name")] 
    public string GameName { get; set; } 
    
    [JsonPropertyName("release_dates")] 
    public List<ReleaseDateItem> ReleaseDates { get; set; } 

    // Optional: Computed property for easy display in ListView
    [JsonIgnore] // Skip during deserialization
    public string DisplayReleaseDate
    {
        get
        {
            if (ReleaseDates == null || !ReleaseDates.Any())
                return "Unknown";
            // Join all release dates with commas, or just take the first one
            return string.Join(", ", ReleaseDates.Select(d => d.HumanReadableDate));
        }
    }
}

Step 2: Fix Deserialization & Loop Logic

Deserialize the response into a list of GameListObject, then iterate over that collection to populate your ObservableCollection:

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; 

    // Reuse HttpClient with using statement to avoid resource leaks
    using var 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); 

    // Build request content (IGDB uses plain text queries, not JSON)
    var content = new StringContent($"search \"{SearchQuery}\"; fields name,release_dates.human;");
    content.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); // Critical for IGDB

    try { 
        HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, content); 
        httpResponseMessage.EnsureSuccessStatusCode(); 
        var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync(); 
        Debug.WriteLine("Request Response: " + httpResponseBody); 

        // Deserialize to a list of GameListObject instead of a single instance
        var gameList = JsonSerializer.Deserialize<List<GameListObject>>(httpResponseBody); 

        if (gameList != null)
        {
            foreach (var gameItem in gameList) 
            { 
                dataList.Add(gameItem);

                // Debug output
                Debug.WriteLine($"id: {gameItem.GameID}"); 
                Debug.WriteLine($"name: {gameItem.GameName}"); 
                Debug.WriteLine($"release dates: {gameItem.DisplayReleaseDate}"); 
            }
        }
    } catch (Exception ex) { 
        Debug.WriteLine(ex); 
    } 
}

3. Key Improvements Explained

  • Correct deserialization: By targeting List<GameListObject>, we match the API's array response, allowing proper iteration with foreach.
  • Model alignment: The ReleaseDates property now maps to the API's array of release date objects, eliminating deserialization errors.
  • Proper HTTP content type: Setting text/plain ensures IGDB understands your query (it doesn't accept JSON for this endpoint).
  • Resource management: Using using with HttpClient prevents memory leaks from unused client instances.
  • Null safety: Checking if gameList is null avoids null reference exceptions if the API returns an empty response.

内容的提问来源于stack exchange,提问作者ThatGuyJacobee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:22:41