Десериализация Json создает нулевой объект

#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 и обеспечит хорошую отправную точку. Вы всегда можете удалить свойства и дочерние элементы, если они вам не нужны.