0

I got json object like this -

enter image description here

and some times like this -

enter image description here

So the order of the object is not fixed. In above example "CreatedOn" field need to stored in DB.

I am using following code to convert it into expandoobject -

    JObject jsonObject = JObject.Parse(json);

    // eval into an expando
    dynamic dynObject = ConvertJTokenToObject(jsonObject);

and here ConvertJTokenToObject -

public object ConvertJTokenToObject(JToken token)
        {
            if (token is JValue)
            {
                return ((JValue)token).Value;
            }

            if (token is JObject)
            {
                ExpandoObject expando = new ExpandoObject();
                (from childToken in ((JToken)token) where childToken is JProperty select childToken as JProperty).ToList().ForEach(property =>
                {
                    ((IDictionary<string, object>)expando).Add(property.Name, ConvertJTokenToObject(property.Value));
                });

                return expando;
            }

            if (token is JArray)
            {
                object[] array = new object[((JArray)token).Count];
                int index = 0;
                foreach (JToken arrayItem in ((JArray)token))
                {
                    array[index] = ConvertJTokenToObject(arrayItem);
                    index++;
                }
                return array;
            }
            throw new ArgumentException(string.Format("Unknown token type '{0}'", token.GetType()), "token");
        }

Now, the issue is that I dont know which "dimension" element will have "CreatedOn" field.

This works good with the first case -

dynObject.context.custom.dimensions[0].CreatedOn

but breaks in another case, as it should be -

dynObject.context.custom.dimensions[1].CreatedOn

How to search expandoobject by fields name like "CreatedOn" , "Status" etc.

Anil Purswani
  • 1,857
  • 6
  • 35
  • 63
  • 1) Newtonsoft has [built-in ability to deserialize to `ExpandoObject`](http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Converters_ExpandoObjectConverter.htm). Just do `dynamic dynObject = jsonObject.ToObject();` 2) But why do this at all? Just stick with `JToken` and use [`SelectToken`](http://www.newtonsoft.com/json/help/html/QueryJsonSelectToken.htm) or [`dynamic`](http://www.newtonsoft.com/json/help/html/QueryJsonDynamic.htm). – dbc Jul 21 '16 at 11:52
  • @dbc, yeah I used SelectToken and it worked! – Anil Purswani Jul 22 '16 at 09:27

2 Answers2

0

Since ExpandoObject implements IDictionary, can't you just do something like:

if (dynObject.context.custom.dimensions[1] as IDictionary<string,object>).ContainsKey("CreatedOn") {
//Your logic here... 
}
Pedro Luz
  • 973
  • 5
  • 14
0

you will have to flatten the Dimensions, I think your problem is not finding a property in expando via name, you can do that by flatting the expando structure by dot notation... i can post somat if you need to know that. But your main issue stems from dimensions being an dynamic[], so you would need to get dimensions like var dimensions = dynObject.Context.Custom.dimensions and then flatten them like var flattened = FlattenDimensions(dimensions) this will give you a dictionary like

enter image description here

Flatten method

private static Dictionary<string, object> FlattenDimensions(dynamic[] dimensions)
    {
        var flattened = new Dictionary<string, object>();
        foreach (var dimension in dimensions)
        {
            var dict = (IDictionary<string, object>)dimension;
            foreach (var item in dict)
            {
                flattened.Add(item.Key, item.Value);
            }
        }
        return flattened;
    }

you can tweak the above method to suit your need better, but its an idea And as you have a flatted dictionary now you can search for CreatedOn or any other property

--hope this makes sense

Preet Singh
  • 1,791
  • 13
  • 16