Использование дженериков в C# для определения подсвойства для десериализации JSON завершается неудачей из-за странности C#

Место общения программистов C#
Ответить
Anonymous
 Использование дженериков в C# для определения подсвойства для десериализации JSON завершается неудачей из-за странности

Сообщение Anonymous »

Я собираюсь реализовать тестовый проект с помощью api-football.com. Их ответы всегда имеют одну и ту же форму — пример можно увидеть здесь. Свойства «Получить», «Параметры», «Ошибки», «Результаты» и «Ответ» всегда находятся в формате JSON, но форма «Ответа» зависит от того, что вы вызываете. Остальные свойства остаются прежними.
Мне было интересно, как смоделировать это на C#, и мне пришла в голову идея использовать Generics для представления свойства Response — таким образом я мог бы обрабатывать множество различных типы ответов в полуэлегантном виде.
Поэтому я создал такой базовый класс:

Код: Выделить всё

public abstract class ApiFootballResponseBase
where TResponse : IApiFootballResponseType
{
public string Get { get; set; }

[JsonConverter(typeof(ApiFootballDictOrEmptyArrayJsonConverter))]
public Dictionary Parameters { get; set; }

[JsonConverter(typeof(ApiFootballDictOrEmptyArrayJsonConverter))]
public Dictionary Errors { get; set; }

public ApiFootballPaging Paging { get; set; }

public int Results { get; set; }

public TResponse Response { get; set; }

[JsonConstructor]
public ApiFootballResponseBase()
{
}
}
IApiFootballResponseType — это просто интерфейс пустого маркера. JsonConverter, используемый с параметрами и ошибками, был написан мной для обработки того факта, что эти поля, когда они пусты, просто устанавливаются в пустой массив ([]), а если они что-то содержат, они представляют собой пакеты свойств, которые я хочу вернуть в виде словарей. JsonConverter был протестирован и работает достаточно хорошо.
Тогда у нас есть пример класса, который я хочу использовать для получения информации о статусе API по URL-адресу, указанному выше.

Код: Выделить всё

public class ApiFootballStatusResponse : IApiFootballResponseType
{

public ApiFootballSubscriptionInformation Subscription { get; set; }
// TODO: Requests

public ApiFootballAccountInformation Account { get; set; }

[JsonConstructor]
public ApiFootballStatusResponse()
{

}
}
Эти типы свойств также представляют собой простые пакеты свойств с аннотациями [JsonConstructor] в конструкторе без параметров.
И причина этого — исключение, которое я получить, когда я пытаюсь десериализовать с помощью RestSharp и System.Text.Json:

Код: Выделить всё

NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'ApiFootball.Responses.ApiFootballResponseBase`1[ApiFootball.Responses.ApiFootballStatusResponse]'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
Однако, как вы можете видеть, я попробовал добавить конструкторы без параметров ко всем классам и пометил их как JsonConstructor (тот, который принадлежит System.Text.Json, а не NewtonSoft).
Это исключение действительно пытается сказать мне что-то еще? Это плохой способ попытаться обработать свойство Response с разным содержимым в зависимости от запрошенного ресурса? Если да, то какой способ избежать необходимости воссоздавать общие свойства всех запросов в разных классах/записях?

Подробнее здесь: https://stackoverflow.com/questions/788 ... fails-with
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»