using System.Text.Json; using System.Text.Json.Serialization; using YandexMusic.API.Converters; using YandexMusic.API.Models.Common; namespace YandexMusic.API.Requests.Common; /// /// Строитель запросов с десериализацией JSON-ответа в TResponse. /// internal abstract class YJsonRequestBuilder : YRequestBuilder { private readonly JsonSerializerOptions _jsonOptions; protected YJsonRequestBuilder(YandexMusicApi api) : base(api) { _jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) } }; } protected virtual async Task DeserializeAsync(HttpResponseMessage response) { var json = await response.Content.ReadAsStringAsync(); var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.KebabCaseLower), new IntToStringConverter(), new StringToIntConverter(), new YExecutionContextConverter(Api, Storage), } }; if (!response.IsSuccessStatusCode) { var error = JsonSerializer.Deserialize(json, options); throw error ?? new Exception($"Ошибка HTTP {response.StatusCode}: {json}"); } try { return JsonSerializer.Deserialize(json, options); } catch (Exception ex) { throw new Exception($"Ошибка десериализации: {ex.Message}\nJSON: {json}", ex); } } protected string SerializeJson(object data) => JsonSerializer.Serialize(data, _jsonOptions); /// /// Выполняет запрос и возвращает десериализованный объект типа TResponse. /// public async Task ExecuteAsync(TParams parameters) { using var response = await ExecuteRawAsync(parameters); return await DeserializeAsync(response); } }