How to check if a JSON output returns 1 or more rows so that either a string or arraylist can be used and mapped accordingly to an object in C#

StackOverflow https://stackoverflow.com/questions/20665637

Question

How can I check if a JSON output returned just 1 row of an element or multiple rows. For example, I have the below JSON output.

{
    "orders": {
        "order": [
            {
                "id": 100,
                "type": "market",
                "symbol": "AAPL",
                "side": "buy"
            }]
    }
}

I have the below code for deserializing the JSON output:

 dynamic dynObj = JsonConvert.DeserializeObject(response);

 Console.WriteLine("ID: {0}\n Type: {1}\n Symbol: {2}\n Side: {3}\n", dynObj.orders.order.id, dynObj.orders.order.type,dynObj.orders.order.symbol,dynObj.orders.order.side;

But, most of the times I get the output as an array of order object as below

 {
        "orders": {
            "order": [
                {
                    "id": 101,
                    "type": "market",
                    "symbol": "AAPL",
                    "side": "buy"
                },
                {
                    "id": 102,
                    "type": "market",
                    "symbol": "MSFT",
                    "side": "buy"
                },
                {
                    "id": 103,
                    "type": "limit",
                    "symbol": "AMZN",
                    "side": "buy"
                }
            ]
        }
    }

So I deserialize the above Json output as shown:

dynamic dynObj = JsonConvert.DeserializeObject(response);

                    foreach (var c in dynObj.orders.order)
                    {
                        Console.WriteLine("Id : {0}\n", c.id);
                        Console.WriteLine("Type : {0}\n", c.type);
                        Console.WriteLine("Symbol : {0}\n", c.symbol);
                        Console.WriteLine("Side : {0}\n", c.side);                           
                    }

I have two important questions:

  1. How can I know whether the JSON returned is only 1 row of Order object or a collection so that I can use the relevant way to loop.
  2. If it is an array, do I need to deserialize as below and if so, how do I add them to Order Class/Object?

    RootObject ord = JsonConvert.DeserializeObject(response);

Any help is greatly appreciated.

Was it helpful?

Solution

I would highly recommend you stop using dynamic because I think this is an abuse of the type. Instead I would define types to deserialize into. By doing so you give yourself type safety and working with the data becomes trivial. Below are class definitions an example using the generic deserialize method (Deserialize<T>(string input)).

 public class order
 {
      public int id { get; set; }
      public string type { get; set; }
      public string symbol { get; set; }
      public string side { get; set; }
 }

 public class orders
 {
      List<order> order { get; set; }
 }

 JsonSerializer serializer = new JsonSerializer();
 orders myOrders = serializer.Deserialize<orders>(response);

 if (myOrders.order.Count() == 1)
   // we have 1 order

OTHER TIPS

Able to fix the issue pertaining to check if the JSON result returned is an object or an array. Modified my RootObject which has the Array/Object as follows:

 [JsonConverter(typeof(GenericListCreationJsonConverter<T>))]
 public List<T> order { get; set; }

Added the below class which checks for JSON

internal class GenericListCreationJsonConverter<T> : JsonConverter
    {

        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                return serializer.Deserialize<List<T>>(reader);
            }
            else
            {
                T t = serializer.Deserialize<T>(reader);
                return new List<T>(new[] { t });
            }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top