fix execute context

This commit is contained in:
FrigaT
2026-04-13 15:41:44 +03:00
parent 21a0c5abe6
commit b8f78a5856
3 changed files with 34 additions and 24 deletions

View File

@@ -1,4 +1,6 @@
internal class Program using YandexMusic.API.Extensions.API;
internal class Program
{ {
private async static Task Main(string[] args) private async static Task Main(string[] args)
{ {
@@ -6,5 +8,9 @@
var type = await client.Authorize("y0__xDy2budARje-AYg7rmliBc11LbYoMeUiwiO6f6mSCAMDYVIKg"); var type = await client.Authorize("y0__xDy2budARje-AYg7rmliBc11LbYoMeUiwiO6f6mSCAMDYVIKg");
var playlists = (await client.GetFavoritesAsync()).Where(t => t.Owner.Uid == client.Account.Uid).ToList(); var playlists = (await client.GetFavoritesAsync()).Where(t => t.Owner.Uid == client.Account.Uid).ToList();
var playlist = await client.GetPlaylistAsync("97ae0768-8a40-8485-9fa4-b6c856bc6b21"); var playlist = await client.GetPlaylistAsync("97ae0768-8a40-8485-9fa4-b6c856bc6b21");
var tracks = await client.GetTracksAsync(new[] { "78412759" });
await playlist.InsertTracksAsync(tracks.ToArray());
} }
} }

View File

@@ -11,13 +11,6 @@ public abstract class CommonRequestProvider : IRequestProvider
/// <summary>Хранилище данных авторизации.</summary> /// <summary>Хранилище данных авторизации.</summary>
protected readonly AuthStorage storage; protected readonly AuthStorage storage;
/// <summary>Настройки сериализации JSON (регистронезависимые, поддержка enum-строк).</summary>
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true,
Converters = { new JsonStringEnumConverter(JsonNamingPolicy.KebabCaseLower), new IntToStringConverter() }
};
/// <summary>Инициализирует новый экземпляр провайдера.</summary> /// <summary>Инициализирует новый экземпляр провайдера.</summary>
/// <param name="authStorage">Хранилище авторизации.</param> /// <param name="authStorage">Хранилище авторизации.</param>
protected CommonRequestProvider(AuthStorage authStorage) protected CommonRequestProvider(AuthStorage authStorage)
@@ -37,6 +30,16 @@ public abstract class CommonRequestProvider : IRequestProvider
{ {
var json = await response.Content.ReadAsStringAsync(); var json = await response.Content.ReadAsStringAsync();
JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true,
Converters = {
new JsonStringEnumConverter(JsonNamingPolicy.KebabCaseLower),
new IntToStringConverter(),
new YExecutionContextConverter(api, storage),
}
};
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
var error = JsonSerializer.Deserialize<YErrorResponse>(json, JsonOptions); var error = JsonSerializer.Deserialize<YErrorResponse>(json, JsonOptions);

View File

@@ -5,7 +5,7 @@ using YandexMusic.API.Common;
namespace YandexMusic.API.Models.Common; namespace YandexMusic.API.Models.Common;
/// <summary>Конвертер для внедрения контекста выполнения (API и хранилище) в модели.</summary> /// <summary>Конвертер для внедрения контекста выполнения (API и хранилище) в модели.</summary>
public class YExecutionContextConverter : JsonConverter<YBaseModel> public class YExecutionContextConverter : JsonConverter<object>
{ {
private readonly YandexMusicApi _api; private readonly YandexMusicApi _api;
private readonly AuthStorage _storage; private readonly AuthStorage _storage;
@@ -16,26 +16,27 @@ public class YExecutionContextConverter : JsonConverter<YBaseModel>
_storage = storage; _storage = storage;
} }
public override YBaseModel? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) public override bool CanConvert(Type typeToConvert) =>
typeof(YBaseModel).IsAssignableFrom(typeToConvert);
public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{ {
// Десериализуем объект без контекста // Убираем этот конвертер из опций, чтобы избежать рекурсии
var obj = (YBaseModel?)JsonSerializer.Deserialize(ref reader, typeToConvert, options); var innerOptions = new JsonSerializerOptions(options);
if (obj != null) innerOptions.Converters.Remove(this);
var obj = JsonSerializer.Deserialize(ref reader, typeToConvert, innerOptions);
if (obj is YBaseModel baseModel)
{ {
obj.Context = new YExecutionContext baseModel.Context = new YExecutionContext { API = _api, Storage = _storage };
{
API = _api,
Storage = _storage
};
} }
return obj; return obj;
} }
public override void Write(Utf8JsonWriter writer, YBaseModel value, JsonSerializerOptions options) public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
{ {
// При сериализации игнорируем контекст var innerOptions = new JsonSerializerOptions(options);
var cloneOptions = new JsonSerializerOptions(options); innerOptions.Converters.Remove(this);
cloneOptions.Converters.Remove(this); JsonSerializer.Serialize(writer, value, innerOptions);
JsonSerializer.Serialize(writer, value, cloneOptions);
} }
} }