JsonDocument.Parse
throws The requested operation requires an element of type 'Object', but the target element has type 'Array'.
, because the message is actually an array. You can see that in the log below.
How can I deal with it?
My code:
private void OnMessageReceived(object? sender, MessageReceivedEventArgs e)
{
_logger.LogTrace("Message was received. {Message}", Encoding.UTF8.GetString(e.Message.Buffer.Span));
using var document = JsonDocument.Parse(e.Message.Buffer);
if (document.RootElement.TryGetProperty("reqid", out var requestIdElement))
{
_logger.LogInformation("REQID");
}
}
My log, which includes the JSON:
[15:17:02 VRB] Connection task started: wss://ws.kraken.com
[15:17:02 VRB] Connecting...
[15:17:09 VRB] OnConnected: Connection opened (URL: wss://ws.kraken.com)
[15:17:09 VRB] Message was received. {"connectionID":8059679396249595639,"event":"systemStatus","status":"online","version":"1.9.0"}
[15:17:09 VRB] Message was received. {"channelID":340,"channelName":"ticker","event":"subscriptionStatus","pair":"XBT/USD","reqid":1,"status":"subscribed","subscription":{"name":"ticker"}}
[15:17:09 INF] REQID
[15:17:09 VRB] Message was received. {"channelID":356,"channelName":"ticker","event":"subscriptionStatus","pair":"XBT/EUR","reqid":1,"status":"subscribed","subscription":{"name":"ticker"}}
[15:17:09 INF] REQID
[15:17:09 VRB] Message was received. [340,{"a":["19183.10000",11,"11.73924682"],"b":["19183.00000",0,"0.00700000"],"c":["19189.90000","0.00001057"],"v":["5483.17940238","8791.76237363"],"p":["19447.36865","19869.35727"],"t":[25966,42418],"l":["18728.00000","18728.00000"],"h":["20740.10000","20995.20000"],"o":["20440.30000","20988.50000"]},"ticker","XBT/USD"]
[15:17:09 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:09 VRB] Message was received. [356,{"a":["18300.10000",6,"6.96418059"],"b":["18300.00000",0,"0.00830972"],"c":["18300.10000","0.00010000"],"v":["2542.62440365","3607.51107542"],"p":["18436.15535","18790.67960"],"t":[32790,49726],"l":["17905.00000","17905.00000"],"h":["19765.20000","20030.50000"],"o":["19482.40000","20030.50000"]},"ticker","XBT/EUR"]
[15:17:09 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:10 VRB] Message was received. {"event":"heartbeat"}
[15:17:10 VRB] Message was received. [356,{"a":["18300.10000",6,"6.96418059"],"b":["18281.10000",0,"0.00566993"],"c":["18281.10000","0.06940181"],"v":["2542.72440365","3607.61107542"],"p":["18436.14941","18790.66558"],"t":[32794,49730],"l":["17905.00000","17905.00000"],"h":["19765.20000","20030.50000"],"o":["19482.40000","20030.50000"]},"ticker","XBT/EUR"]
[15:17:10 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:10 VRB] Message was received. [340,{"a":["19183.10000",18,"18.23619321"],"b":["19183.00000",0,"0.01700000"],"c":["19183.10000","0.00052110"],"v":["5483.17992348","8791.76289473"],"p":["19447.36863","19869.35723"],"t":[25967,42419],"l":["18728.00000","18728.00000"],"h":["20740.10000","20995.20000"],"o":["20440.30000","20988.50000"]},"ticker","XBT/USD"]
[15:17:10 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:11 VRB] Message was received. {"event":"heartbeat"}
[15:17:11 VRB] Message was received. [356,{"a":["18284.20000",0,"0.02704155"],"b":["18281.20000",0,"0.03883245"],"c":["18284.20000","0.00027995"],"v":["2542.72468360","3607.61135537"],"p":["18436.14939","18790.66554"],"t":[32795,49731],"l":["17905.00000","17905.00000"],"h":["19765.20000","20030.50000"],"o":["19482.40000","20030.50000"]},"ticker","XBT/EUR"]
[15:17:11 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:11 VRB] Message was received. [356,{"a":["18283.00000",1,"1.30361502"],"b":["18281.20000",0,"0.03883245"],"c":["18283.00000","0.00060000"],"v":["2542.72528360","3607.61145187"],"p":["18436.14936","18790.66529"],"t":[32796,49730],"l":["17905.00000","17905.00000"],"h":["19765.20000","20030.50000"],"o":["19482.40000","20030.50000"]},"ticker","XBT/EUR"]
[15:17:11 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:11 VRB] Message was received. [340,{"a":["19183.10000",18,"18.48100120"],"b":["19178.00000",0,"0.00010000"],"c":["19183.00000","0.01000000"],"v":["5483.19692348","8791.77989473"],"p":["19447.36781","19869.35590"],"t":[25969,42421],"l":["18728.00000","18728.00000"],"h":["20740.10000","20995.20000"],"o":["20440.30000","20988.50000"]},"ticker","XBT/USD"]
[15:17:11 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:12 VRB] Message was received. {"event":"heartbeat"}
[15:17:13 VRB] Message was received. {"event":"heartbeat"}
[15:17:13 VRB] Message was received. [356,{"a":["18281.40000",0,"0.36978062"],"b":["18280.90000",0,"0.00059082"],"c":["18281.40000","0.05021938"],"v":["2542.77550298","3607.66167125"],"p":["18436.14630","18790.65820"],"t":[32797,49731],"l":["17905.00000","17905.00000"],"h":["19765.20000","20030.50000"],"o":["19482.40000","20030.50000"]},"ticker","XBT/EUR"]
[15:17:13 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:13 VRB] Message was received. [340,{"a":["19178.10000",13,"13.16759732"],"b":["19173.70000",0,"0.07544241"],"c":["19178.00000","0.00010000"],"v":["5483.19702348","8791.72817814"],"p":["19447.36780","19869.34930"],"t":[25970,42419],"l":["18728.00000","18728.00000"],"h":["20740.10000","20995.20000"],"o":["20440.30000","20989.60000"]},"ticker","XBT/USD"]
[15:17:13 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
[15:17:14 VRB] Message was received. {"event":"heartbeat"}
[15:17:14 VRB] Message was received. [356,{"a":["18280.90000",1,"1.09763896"],"b":["18280.80000",0,"0.05424140"],"c":["18280.90000","0.00236104"],"v":["2542.77786402","3607.66403229"],"p":["18436.14616","18790.65786"],"t":[32798,49732],"l":["17905.00000","17905.00000"],"h":["19765.20000","20030.50000"],"o":["19482.40000","20030.50000"]},"ticker","XBT/EUR"]
[15:17:14 ERR] Data loop: The requested operation requires an element of type 'Object', but the target element has type 'Array'.
I found this thread on SO talking about JsonArray? array = JsonNode.Parse(stream)?.AsArray();
. The issue is that it requires a stream. The websocket client library I'm using, returns ReadOnlyMemory<byte>
only (e.Message.Buffer = ReadOnlyMemory<byte>
).
CodePudding user response:
Your problem is not with JsonDocument.Parse(e.Message.Buffer)
, it's with the next line:
if (document.RootElement.TryGetProperty("reqid", out var requestIdElement))
As explained in the documentation for JsonElement.TryGetProperty()
, if the element is a JSON array rather than a JSON object, this method will throw the exception you see:
Exceptions
InvalidOperationException
This value'sValueKind
is not Object.
And in fact, your root JSON value is sometimes an object:
{"connectionID":8059679396249595639,"event":"systemStatus","status":"online","version":"1.9.0"}
But sometimes an array, causing your exception:
[340,{"a":["19183.10000",11,"11.73924682"],"b":["19183.00000",0,"0.00700000"],"c":["19189.90000","0.00001057"],"v":["5483.17940238","8791.76237363"],"p":["19447.36865","19869.35727"],"t":[25966,42418],"l":["18728.00000","18728.00000"],"h":["20740.10000","20995.20000"],"o":["20440.30000","20988.50000"]},"ticker","XBT/USD"]
Since it seems you want to log "reqid"
only if present, you may check document.RootElement.ValueKind == JsonValueKind.Object
before calling TryGetProperty()
like so:
if (document.RootElement.ValueKind == JsonValueKind.Object && document.RootElement.TryGetProperty("reqid", out var requestIdElement))
{
_logger.LogInformation("REQID");
}
You also wrote,
I found this thread on SO talking about
JsonArray? array = JsonNode.Parse(stream)?.AsArray();
. The issue is that it requires a stream. The websocket client library I'm using, returnsReadOnlyMemory<byte>
only (e.Message.Buffer = ReadOnlyMemory<byte>
).
There is an overload JsonNode.Parse(ReadOnlySpan<Byte>, Nullable<JsonNodeOptions>, JsonDocumentOptions)
, however switching to the JsonNode
API is independent of your actual problem, which is that you must test that the incoming JSON is actually an object before attempting to fetch a property value.