KrakenSubscribeRequest.Details
is expected to be polymorphic, but it isn't and the interval property is left behind. If KrakenSubscribeRequest
was polymorphic, it would've worked with the code below, but in this case KrakenSubscribeRequest.Details
is.
var request = new KrakenSubscribeRequest("ohlc", 1, "XBT/USD") { Details = new KrakenOhlcSubscriptionDetails(15) };
// Polymorphic serialization https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-polymorphism
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var json = JsonSerializer.Serialize(request, request.GetType(), options);
Actual
{
"event": "subscribe",
"reqid": 1,
"pair": [
"XBT/USD"
],
"subscription": {
"name": "ohlc"
}
}
Expected
{
"event": "subscribe",
"reqid": 1,
"pair": [
"XBT/USD"
],
"subscription": {
"interval": 15,
"name": "ohlc"
}
}
Objects
public record KrakenSubscribeRequest
{
public KrakenSubscribeRequest(string topic, long requestId, params string[] symbols)
{
RequestId = requestId;
Details = new KrakenSubscriptionDetails(topic);
if (symbols.Any())
{
Symbols = symbols;
}
}
[JsonPropertyName("event")]
public string Event { get; init; } = "subscribe";
[JsonPropertyName("reqid")]
public long RequestId { get; init; }
[JsonPropertyName("pair")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string[]? Symbols { get; init; }
[JsonPropertyName("subscription")]
public KrakenSubscriptionDetails Details { get; init; }
[JsonIgnore]
public int? ChannelId { get; set; }
}
public record KrakenSubscriptionDetails
{
public KrakenSubscriptionDetails(string topic)
{
Topic = topic;
}
[JsonPropertyName("name")]
public string Topic { get; init; }
[JsonIgnore]
public virtual string ChannelName => Topic;
}
public record KrakenOhlcSubscriptionDetails : KrakenSubscriptionDetails
{
public KrakenOhlcSubscriptionDetails(int interval) : base("ohlc")
{
Interval = interval;
}
[JsonPropertyName("interval")]
public int Interval { get; init; }
[JsonIgnore]
public override string ChannelName => $"ohlc-{Interval}";
}
Edit
This solves the issue but I would like to get a more generic way.
public class KrakenSubscriptionDetailsConverter : JsonConverter<KrakenSubscriptionDetails>
{
/// <inheritdoc />
public override bool CanConvert(Type objectType)
{
return typeof(KrakenSubscriptionDetails).IsAssignableFrom(objectType);
}
/// <inheritdoc />
public override KrakenSubscriptionDetails Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, KrakenSubscriptionDetails value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
}
}