#c# #asp.net-mvc
#c# #asp.net-mvc
Вопрос:
json можно найти здесь: https://www.googleapis.com/books/v1/volumes ?q = Гарри Поттер
У меня возникли проблемы с десериализацией json в список объектов книги. Я использую две модели: BookList и Books. Список книг имеет свойство bookList, которое представляет собой просто список книг.
При запуске кода создается объект списка книг, но его значение равно нулю.
Вот код:
BookList.cs
using System.Collections.Generic;
using Newtonsoft.Json;
namespace HarryPotterBooksApp.Models
{
public class BookList
{
[JsonProperty("items")]
public List<Book> bookList {get;set;}
}
}
Book.cs
using Newtonsoft.Json;
namespace HarryPotterBooksApp.Models
{
public class Book
{
[JsonProperty("id")]
public string id { get; set; }
[JsonProperty("publisher")]
public string publisher { get; set; }
}
}
BookController.cs
namespace HarryPotterBooksApp.Controllers {
public class BooksController: Controller {
const string BASE_URL = "https://www.googleapis.com/books/v1/volumes?q=harry potter";
private readonly ILogger<BooksController> _logger;
private readonly IHttpClientFactory _clientFactory;
public BookList Books { get; set; }
public bool GetBooksError { get; private set; }
public BooksController (ILogger<BooksController> logger, IHttpClientFactory clientFactory)
{
_logger = logger;
_clientFactory = clientFactory;
}
public async Task<IActionResult> Index ()
{
var message = new HttpRequestMessage ();
message.Method = HttpMethod.Get;
message.RequestUri = new Uri ($"{BASE_URL}api/Books");
message.Headers.Add ("Accept", "application/json");
var client = _clientFactory.CreateClient ();
var response = await client.SendAsync (message);
if (response.IsSuccessStatusCode) {
var responseString = await response.Content.ReadAsStringAsync();
Books = JsonConvert.DeserializeObject<BookList>(responseString);
} else {
GetBooksError = true;
Books = new BookList();
}
return View (Books);
}
Комментарии:
1. И в чем проблема или ваш вопрос?
Ответ №1:
Вы видели новую библиотеку Microsoft для десериализации JSON? Это называется System.Text.Json, и это удивительно: https://learn.microsoft.com/fr-fr/dotnet/api/system.text.json?view=netcore-3.1
Также у вас есть Json.NET от Newtonsoft: https://www.newtonsoft.com/json
Ваш JSON кажется довольно сложным, решение состоит в том, чтобы записать каждый объект и десериализовать JSON с каждым объектом (но это будет слишком долго). Другим решением является построение представления путем получения всего свойства.
Комментарии:
1. Что вы подразумеваете под: Другим решением является создание представления путем получения всего свойства.
2. Выполните итерацию по всему элементу с помощью класса JsonElement: learn.microsoft.com/fr-fr/dotnet/api /…
Ответ №2:
Ваша модель не соответствует исходному JSON, так что это будет первой проблемой. JSON имеет один корневой объект — корень не является списком. Этот корень содержит kind, totalItems и items . Список книг — это «элементы». Вам нужна модель, которая соответствует этому. Аналогично, идентификатор находится в объекте item (вашей книги), но издатель находится в дочернем объекте (volumeInfo). Если ваша модель не соответствует, то ваш вызов DeserializeObject не будет работать.
Учитывая сложность возвращаемого JSON, возможно, самый простой способ убедиться, что ваша модель соответствует этому JSON, — сгенерировать модель с помощью инструмента, такого как https://json2csharp.com / или https://app.quicktype.io/?l=csharp , который построит модель C # из примера JSON. Это гарантирует, что ваша модель соответствует JSON и обеспечит хорошую отправную точку. Вы всегда можете удалить свойства и дочерние элементы, если они вам не нужны.