Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identifying that a property's value is an array

Tags:

json

c#

json.net

I have a JSON file:

{  
   "abn":"63119059513",
   "acn":"119059513",
   "business_structure":"Private Company",
   "ngr_number":"1231231",
   "cbh_number":"1231231",
   "main_name":"Brickworks Building Products Pty Ltd",
   "trading_name":"Brickworks",
   "other_trading_names":"Austral Bricks",
   "directors":[  
      {  
         "ID":"12114",
         "ae_forms_filled_in_ID":"22739",
         "name":"John Smith",
         "dob":"1983-10-29",
         "address_line_1":"123 Fake Street",
         "address_line_2":"",
         "address_line_city":"Fakeland",
         "address_line_postcode":"2000",
         "address_line_state":"New South Wales",
         "address_line_country":"Australia",
         "order_extract_id":null,
         "director_found":null,
         "drivers_lic":"",
         "home_mortgage":"",
         "phone":"",
         "mobile":"",
         "director_email":"",
         "director_title":"Mr",
         "director_position":"Director",
         "dir_pdf_url":null
      }
   ],

}

I want to determine if the value of any property has a structure of an array. The best I can come up with so far is:

StreamReader streamrr = new StreamReader("C:\\temp\\agfarm_example_udate.json", Encoding.UTF8);

string JSON = streamrr.ReadToEnd();

JObject CWFile = JObject.Parse(JSON);
foreach (JProperty property in CWFile.Properties())
{
    // Do something

    if (property.Value.ToString().Contains("["))
    {
        // Do something with the array
        JArray items = (JArray)CWFile[property.Name];

        foreach (JObject o in items.Children<JObject>())
        {
            foreach (JProperty p in o.Properties())
            {
               // Do something
            }
        }
    }
}

To determine whether or not a property value has an array, I used the condition:

if (property.Value.ToString().Contains("["))

I'm just wondering if there is a better way of doing this check?

like image 879
Stanza Avatar asked Jan 20 '15 00:01

Stanza


1 Answers

One way to do this is to check the JToken.Type property. Arrays are of type JTokenType.Array:

if (property.Value.Type == JTokenType.Array)
{
    var items = (JArray)property.Value;

    // Proceed as before.
}

Or, you can just try to cast to JArray:

if (property.Value is JArray)
{
    var items = (JArray)property.Value;

    // Proceed as before.
}

Both are preferable to checking property.Value.ToString().Contains("[") since a nested property might have an array value, thus causing a bracket to appear somewhere in the ToString() return.

If you want to recursively find every property with an array value, you can introduce an extension method:

public static class JsonExtensions
{
    public static IEnumerable<JToken> WalkTokens(this JToken node)
    {
        if (node == null)
            yield break;
        yield return node;
        foreach (var child in node.Children())
            foreach (var childNode in child.WalkTokens())
                yield return childNode;
    }
}

And then do:

var CWFile = JToken.Parse(JSON)
var arrayProperties = CWFile.WalkTokens().OfType<JProperty>().Where(prop => prop.Value.Type == JTokenType.Array);
like image 153
dbc Avatar answered Sep 17 '22 20:09

dbc