我正在尝试使用rawg api并从他们的api中获取游戏,我已经创建了要解析数据的游戏实体类
//game entity
public class Game
{
public int Id { get; set; }
public string Slug { get; set; }
public string Name { get; set; }
public string Released { get; set; }
public string Background_Image { get; set; }
public int Rating { get; set; }
public int Playtime { get; set; }
}现在我需要从api中获取游戏,我创建了这个方法
public static async Task<List<Game>> ApiRawgGamesRequest()
{
var gamesList = new List<Game>();
for (int i = 1; i < 250; i++)
{
using (var msg = new HttpRequestMessage(HttpMethod.Get, new Uri($"https://api.rawg.io/api/games?page_size=40&page={i}")))
using (var response = await _client.SendAsync(msg))
{
response.EnsureSuccessStatusCode();
var gamesResponse = await response.Content.ReadAsAsync<Game[]>();
gamesList.AddRange(gamesResponse);
}
}
return gamesList;
}我尽量不要一次添加所有的游戏,所以我使用了一个for循环来不断地将游戏添加到列表中,以潜在地减轻压力。但是我得到了一个错误
// error
Unhandled exception. System.AggregateException: One or more errors occurred. (Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Domain.Game[]' because the t
ype requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a
collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'count', line 1, position 9.)来自rawg api的响应如下所示--结果部分是我试图收集的游戏数据
// api response
{
"count": 454988,
"next": "https://api.rawg.io/api/games?page=2&page_size=40",
"previous": null,
"results": [
{
"id": 3498,
"slug": "grand-theft-auto-v",
"name": "Grand Theft Auto V",
"released": "2013-09-17",
"tba": false,
"background_image": "https://media.rawg.io/media/games/84d/84da2ac3fdfc6507807a1808595afb12.jpg",
"rating": 4.48,
},
{
"id": 4200,
"slug": "portal-2",
"name": "Portal 2",
"released": "2011-04-18",
"tba": false,
"background_image": "https://media.rawg.io/media/games/328/3283617cb7d75d67257fc58339188742.jpg",
"rating": 4.62
}
]
}有没有更好的方法来做这件事?
发布于 2020-10-13 06:19:49
您的异常是由错误的JSON解析对象引起的。
在您的代码中,您将调用:
var gamesResponse = await response.Content.ReadAsAsync<Game[]>();但是响应是对象(来自您的示例JSON):
public class GameResponse
{
public int Count { get; set; }
public string Next{ get; set; }
public string Previous { get; set; }
public IEnumerable<Game> Results { get; set; }
}如果将其更改为:
var gamesResponse = await response.Content.ReadAsAsync<GameResponse>();您将成功解析响应并通过以下方式访问游戏:
gamesResponse.Results发布于 2020-10-13 06:22:53
因此,您试图只反序列化json的“result”部分,您必须使用来自响应json的所有项来构建一个类。
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Result {
public int id { get; set; }
public string slug { get; set; }
public string name { get; set; }
public string released { get; set; }
public bool tba { get; set; }
public string background_image { get; set; }
public double rating { get; set; }
}
public class Root {
public int count { get; set; }
public string next { get; set; }
public object previous { get; set; }
public List<Result> results { get; set; }
}你可以随时在线使用某种Json>class生成器,使用下面的代码:https://json2csharp.com/
发布于 2020-10-13 06:40:27
对于结构不正确的问题,有几个很好的答案。我在这里添加的唯一一件事是注释,这是一种良好的做法,也是为了更好地控制您的变量名称。请注意,DataContract和DataMember是框架的一部分,但它们可以很好地与Json.Net一起工作,即使Json.Net提供了自己的一组注释。
[DataContract]
public class Payload
{
[DataMember(Name = "count")]
public int Count { get; set; }
[DataMember(Name = "next")]
public string Next { get; set; }
[DataMember(Name = "previous")]
public string Previous { get; set; }
[DataMember(Name = "results")]
public List<GameData> Results { get; set; }
}
[DataContract]
public class GameData
{
[DataMember(Name = "id")]
public long Id { get; set; }
[DataMember(Name = "slug")]
public string Slug { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "rating")]
public float Rating { get; set; }
[DataMember(Name = "rating_top")]
public float Rating_top { get; set; }
}
public static async Task<IEnumerable<Payload>> GetGameDatasAsync(int page = 1, int pageSize = 40, bool followNext = false, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
string next = $"https://api.rawg.io/api/games?page_size={pageSize}&page={page}";
var results = new List<Payload>();
using (var client = new HttpClient())
do
{
var result = await client.GetAsync(next, cancellationToken);
next = string.Empty;
if (result.IsSuccessStatusCode)
{
var json = await result.Content.ReadAsStringAsync();
if (!string.IsNullOrWhiteSpace(json))
{
var payload = JsonConvert.DeserializeObject<Payload>(json);
next = payload.Next;
results.Add(payload);
}
}
} while (!string.IsNullOrWhiteSpace(next) && followNext);
return results;
}https://stackoverflow.com/questions/64325718
复制相似问题