调用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_datesis an array, not a string: YourGameListObjectdefinesReleaseDateas a string, but the API returns a collection of release date objects (each with anidand 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
ReleaseDatesproperty now maps to the API's array of release date objects, eliminating deserialization errors. - Proper HTTP content type: Setting
text/plainensures IGDB understands your query (it doesn't accept JSON for this endpoint). - Resource management: Using
usingwithHttpClientprevents memory leaks from unused client instances. - Null safety: Checking if
gameListis null avoids null reference exceptions if the API returns an empty response.
内容的提问来源于stack exchange,提问作者ThatGuyJacobee
相关产品推荐
相关产品推荐

