Reputation: 6331
System.Text.Json.JsonException: The JSON value could not be converted to Models.Side. Path: $.S | LineNumber: 0 | BytePositionInLine: 107.
{
"stream": "c3uwBXY4P4eHD2HNkk5Tmj9SzXKZHRfxMpiWrQsXkvICePRWecoN5gFInj6O",
"data": {
"e": "executionReport",
"E": 1656027820175,
"s": "BTCUSDT",
"c": "electron_77d6dd561690469e8fdfe178738",
"S": "BUY",
"o": "LIMIT",
"f": "GTC",
"q": "0.00105000",
"p": "19000.00000000",
"P": "0.00000000",
"F": "0.00000000",
"g": -1,
"C": "",
"x": "NEW",
"X": "NEW",
"r": "NONE",
"i": 11203182805,
"l": "0.00000000",
"z": "0.00000000",
"L": "0.00000000",
"n": "0",
"N": null,
"T": 1656027820174,
"t": -1,
"I": 23804088798,
"w": true,
"m": false,
"M": false,
"O": 1656027820174,
"Z": "0.00000000",
"Y": "0.00000000",
"Q": "0.00000000"
}
}
public readonly struct Side
{
private Side(string value)
{
Value = value;
}
public static Side Buy => new("BUY");
public static Side Sell => new("SELL");
public string Value { get; }
public static implicit operator string(Side enm)
{
return enm.Value;
}
public override string ToString()
{
return Value;
}
}
public record BinanceStreamOrderUpdate
{
[JsonPropertyName("i")]
public long Id { get; init; }
[JsonPropertyName("s")]
public string Symbol { get; init; } = null!;
[JsonPropertyName("c")]
public string ClientOrderId { get; init; } = null!;
[JsonPropertyName("S")]
public Side Side { get; init; }
[JsonPropertyName("o")]
public SpotOrderType Type { get; init; }
[JsonPropertyName("f")]
public TimeInForce TimeInForce { get; init; }
[JsonPropertyName("q")]
public decimal Quantity { get; init; }
[JsonPropertyName("p")]
public decimal Price { get; init; }
[JsonPropertyName("P")]
public decimal StopPrice { get; init; }
[JsonPropertyName("d")]
public int? TrailingDelta { get; init; }
[JsonPropertyName("F")]
public decimal IcebergQuantity { get; init; }
[JsonPropertyName("C")]
public string? OriginalClientOrderId { get; init; }
[JsonPropertyName("x")]
public ExecutionType ExecutionType { get; init; }
[JsonPropertyName("X")]
public OrderStatus Status { get; init; }
[JsonPropertyName("r")]
public OrderRejectReason RejectReason { get; init; }
[JsonPropertyName("l")]
public decimal LastQuantityFilled { get; init; }
[JsonPropertyName("z")]
public decimal QuantityFilled { get; init; }
[JsonPropertyName("L")]
public decimal LastPriceFilled { get; init; }
[JsonPropertyName("n")]
public decimal Fee { get; init; }
[JsonPropertyName("N")]
public string FeeAsset { get; init; } = string.Empty;
[JsonPropertyName("T")]
[JsonConverter(typeof(MillisecondEpochDateTimeConverter))]
public DateTime UpdateTime { get; init; }
[JsonPropertyName("t")]
public long TradeId { get; init; }
[JsonPropertyName("w")]
public bool IsWorking { get; init; }
[JsonPropertyName("m")]
public bool BuyerIsMaker { get; init; }
[JsonPropertyName("O")]
[JsonConverter(typeof(MillisecondEpochDateTimeConverter))]
public DateTime CreateTime { get; init; }
[JsonPropertyName("Z")]
public decimal QuoteQuantityFilled { get; init; }
[JsonPropertyName("Q")]
public decimal QuoteQuantity { get; init; }
[JsonPropertyName("Y")]
public decimal LastQuoteQuantity { get; init; }
[JsonPropertyName("g")]
public long OrderListId { get; init; }
[JsonPropertyName("I")]
public long I { get; init; }
[JsonPropertyName("M")]
public bool M { get; init; }
}
public Task<SubscriptionToken> SubscribeToUserDataUpdatesAsync(string listenKey,
Func<BinanceStreamOrderUpdate, ValueTask> onOrderUpdateMessage,
Func<BinanceStreamOrderList, ValueTask> onOcoOrderUpdateMessage,
Func<BinanceStreamPositionsUpdate, ValueTask> onAccountPositionMessage,
Func<BinanceStreamBalanceUpdate, ValueTask> onAccountBalanceUpdate)
{
var handler = new Func<string, ValueTask>(data =>
{
using var document = JsonDocument.Parse(data);
if (!document.RootElement.TryGetProperty("data", out var dataElement))
{
return ValueTask.CompletedTask;
}
if (dataElement.TryGetProperty("e", out var eElement))
{
var e = eElement.GetString();
switch (e)
{
case "outboundAccountPosition":
break;
case "balanceUpdate":
break;
case "executionReport":
var result = dataElement.Deserialize<BinanceStreamOrderUpdate>();
return onOrderUpdateMessage(result!);
case "listStatus":
break;
}
}
return ValueTask.CompletedTask;
});
return _client.SubscribeAsync(listenKey, handler);
}
Upvotes: 0
Views: 369
Reputation: 35037
Side
, SpotOrderType
, etc. really look like enums. You can use the native JsonStringEnumConverter
to do the work:
public enum Side {
Buy = 0,
Sell = 1
};
public record BinanceStreamOrderUpdate
{
[JsonConverter(typeof(JsonStringEnumConverter))]
[JsonPropertyName("S")]
public Side? Side { get; init; }
};
public static async Task Main()
{
var json = "{ \"S\": \"BUY\"}";
var o = JsonSerializer.Deserialize<BinanceStreamOrderUpdate>(json);
Console.WriteLine(o);
}
This prints:
BinanceStreamOrderUpdate { Side = Buy }
Upvotes: 1