bretddog
bretddog

Reputation: 5529

JArray.Load, not loading array? wrong format?

Trying to get this Bitfinex api library working, but get this exception.

A normal response.Content is

[["tBTCUSD",5694.5,90.04753567,5694.6,90.83915407,-155.4,-0.0266,5694.6,68727.10536905,6007.8,5537]]

and an error response.Content is

“[\”error\”,20060,\”maintenance”\]”

The normal response produces an exception

ArgumentException...Can not convert Array to String

at

var array = JArray.Load(reader); 
if((string)array[0] == "error")   // exception

I'm new to json, so there may well be a basic formatting issue here with the reader content. It seems this string is not converted to an array, and hence the array[0] holds an array..?

enter image description here

EDIT:

On further thought, I speculate the API content format may have changed. In case, it seems this may work to check for "error" at first element of an error-response :

 if ( array[0].GetType().IsAssignableFrom(typeof(string)) && (string)array[0] == "error")

Upvotes: 1

Views: 758

Answers (1)

dbc
dbc

Reputation: 117086

When the response is valid, the JSON contains an array of arrays of values. When the response is invalid, it contains an array of values, the first of which is the string "error".

Therefore, after parsing with LINQ to JSON, you need to check the JToken.Type type of the first element in the outer array before casting it to a string (or an array), e.g. like so:

var array = JArray.Load(reader); 

if (array.Count > 0 && array[0].Type == JTokenType.String && (string)array[0] == "error")
{
    // Process an error response
    Console.WriteLine("Error response detected.");
}
else if (array.Count > 0 && array[0].Type == JTokenType.Array)
{
    // Process a successful response.
    Console.WriteLine("Normal response detected, array value: ");
    var arrayValue = (JArray)array[0];              
    Console.WriteLine(arrayValue);          
}
else
{
    // Completely unexpected response.
    throw new JsonException("Unexpected response");
}

Similarly, you could check to see whether array[0] is of .Net type JArray or JValue.

The operator you are using in the expression (string)array[0] -- JTokenExplicit Conversion (JToken to String) -- does not re-serialize an arbitrary JToken to JSON. Instead, it converts that JToken to a string only if it represents a primitive value such as a string or an integer. If you want to re-serialize array[0] to JSON you would need to use the ToString() method like so:

if (array.Count > 0 && array[0].ToString(Formatting.None) == "\"error\"")
{
    // Process an error response                
}
else // Continue as before
{
}

However this will have worse performance than simply checking the type.

Sample fiddle.

Upvotes: 1

Related Questions