Десериализация в класс работает неправильно

Попытка захватить Digicert Automation API с помощью Refit HttpClient Factory.

Когда объявлен мой метод интерфейса, который возвращает строку Task<string> GetAgentList([Body] GetAgentListReq req); По возвращенной строке я вижу, что получаю ожидаемый результат JSON от API. В частности, член data возвращает член agentList с массивом агентов JSON.

Когда я меняю метод интерфейса, чтобы вернуть определенный класс результата Task<AgentList> GetAgentList([Body] GetAgentListReq req); Десериализация происходит без создания исключения, но член data.agentList имеет значение null.

Поскольку прямая десериализация строки с использованием System.Text.Json.JsonSerializer.Deserialize<AgentList> также возвращает объект с нулевым членом data.agentList, я буду действовать, исходя из предположения, что мой класс в чем-то неправильный. Если я решу эту проблему, я опубликую ответ.

Вот мой интерфейс и классы:

using Refit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Digicert.Automation.API.Client
{
    [Headers("X-DC-DEVKEY: redacted")]
    public interface IDigicertAutomation
    {


        [Post("/agent/basicdetails")]
        Task<ApiResponse<IEnumerable<AgentSummary>>> GetAgentSummary(AgentSummaryReq req);

        [Post("/agent/list")]
        //Task<string> GetAgentList([Body] GetAgentListReq req);
        Task<AgentList> GetAgentList([Body] GetAgentListReq req);
    }



    public class AgentSummaryReq
    {
        public required string licensekey { get; set; }
        public int accountId { get; set; }
        public int divisionId { get; set; }
    }


    public class GetAgentListReq
    {
        public int accountId { get; set; }
        public class Criterion
        {
            public required string key;
            public required string operation;
            public required List<string> value;
        }
        public required Criterion[] searchCriteriaList { get; set; }
        public required int[] divisionIds { get; set; }
        public int startIndex;
        public int pageSize;
        public required Dictionary<string, string> sorting { get; set; }
    }

    public class Error
    {
        public required string message { get; set; }
        public required List<string> detailedMessage { get; set; }
        public required string errorCode { get; set; }
    }

    public class AgentSummary
    {
        public required Error error { get; set; }
        public class Data
        {
            public required string licenseKey { get; set; }
            public required string agentName { get; set; }
            public int updatePreference { get; set; }
            public required string stateString { get; set; }
            public required string agentVersion { get; set; }
            public bool updateAvailable { get; set; }
            public bool publishUpgradeOption { get; set; }
            public required string emailAddresses { get; set; }
        }
        public required Data data { get; set; }
    }
    public class AgentList
    {
        public required string error { get; set; }
        public class AgentListdata
        {
            public required List<AgentInfo> agentList;
        } 
        public required AgentListdata data {get;set;}
    }

    public class AgentInfo
    {

        public int agentId { get; set; }
        public required string accountId { get; set; }
        public required string divisionId { get; set; }
        public required string hostname { get; set; }
        public required string agentName { get; set; }
        public required string status { get; set; }
        public required string sensorName { get; set; }
        public required string type { get; set; }
        public required string agentLicense { get; set; }
        public int updatePreference { get; set; }
        public bool updateAvailable { get; set; }

    }
}

И мое консольное приложение, вызывающее API:

using Microsoft.Extensions.Hosting;
using Refit;
using Digicert.Automation.API;
using Microsoft.Extensions.DependencyInjection;
using Digicert.Automation.API.Client;
using static Digicert.Automation.API.Client.GetAgentListReq;
using System.Diagnostics;

namespace ConsoleApp1
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            using IHost host = Host.CreateDefaultBuilder(args)
                .ConfigureServices((_, services) =>
                {
                    services
                    .AddRefitClient<IDigicertAutomation>()
                    .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://caas.digicert.com/automationws/v1/"));
                }).Build();

            var automationClient = host.Services.GetRequiredService<IDigicertAutomation>();

            var sorting = new Dictionary<string, string>
            {
                { "AGENTNAME", "ASC" },
            };
            var req = new GetAgentListReq() { accountId = 1349264, searchCriteriaList = Array.Empty<Criterion>(), divisionIds = Array.Empty<int>(), startIndex = 0, pageSize = 50, sorting = sorting };


            var results = await automationClient.GetAgentList(req);
            //var result = results.Content;
            //var x = results.RequestMessage?.Content;
            
            //if (result?.data != null && result?.data.agentList != null)
            //{
            //    foreach (var a in result.data.agentList)
            //    {
            //        Console.Out.WriteLine(a.agentName);
            //    }
            //}
        }
    }
}

Если вы посмотрите документацию, то увидите, что вам не хватает двух параметров totalCount и totalPages в типе AgentListdata.

Orace 25.06.2024 17:49

Если вы замените возвращаемый тип GetAgentList на Task<ApiResponse<AgentList>>, вы сможете получить больше информации о том, почему десериализация не удалась.

Orace 25.06.2024 17:51

Кажется, это общее имя... перезапуск с нуля с ответом второго пилота «дайте мне классы для десериализации этого JSON» вернул меня в нужное русло.

Ross Presser 25.06.2024 20:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это был лучший набор классов для десериализации возвращаемого JSON. Некоторые из них помечены как обязательные, а другие помечены как обнуляемые. Обязательные были добавлены сначала для подавления предупреждений, затем, очевидно, некоторые поля отсутствовали в возвращаемом JSON, поэтому мне пришлось вернуть этим свойствам значение nullable.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Digicert.Automation.API.Client
{
    using System.Collections.Generic;
    using System.Text.Json.Serialization;

    public class AgentList
    {
        public required object Error { get; set; }
        public required Data Data { get; set; }
    }

    public class Data
    {
        public double totalCount { get; set; }
        public double totalPages { get; set; }
        public required List<Agent> AgentList { get; set; }
    }

    public class Agent
    {
        public double AgentId { get; set; }
        public required string AccountId { get; set; }
        public required string DivisionId { get; set; }
        public required string Hostname { get; set; }
        public required string AgentName { get; set; }
        public required string Status { get; set; }
        public string? SensorLicenseKey { get; set; }
        public required string SensorName { get; set; }

        public string? HostIp { get; set; }
        public required string Type { get; set; }
        public string? AgentLicense { get; set; }
        public double UpdatePreference { get; set; }
        public bool UpdateAvailable { get; set; }
        public required string Tag { get; set; }
        public string? OsName { get; set; }
        // Add additional fields as necessary
    }


}

Другие вопросы по теме