1

A dynamic object is generated using a Json deserializing component (Jil) I am using, and I am able to access the properties directly. But I don't know their names in advance, so I am trying to get the names with reflection. I tried doing this:

var props = myDynObj.GetType().GetProperties();

but the page times out. Doesn't give me anything in debugger, just sits there doing nothing, or something and not telling me.

This even happens when I even do this:

var t = myDynObj.GetType();

But when I do this, it works:

var val = myDynObj.MyStaticValue1

Just can't really do anything else with it. Anyonw know why, and how I can get this to work?

RealWorldCoder
  • 1,031
  • 1
  • 10
  • 16
  • Can you provide more information about the Json deserializing? The 'GetType' call works for normal objects when you put them in a dynamic variable. – Bas Oct 15 '14 at 05:29
  • The type of the object is `dynamic {JSON.DeserializeDynamic.JsonObject}` , that's all it tells me in debugger, but once I try to call `GetType()` on it, the page times out. – RealWorldCoder Oct 15 '14 at 05:32
  • 1
    I think this SO question address the same problem you are having: http://stackoverflow.com/questions/2634858/how-do-i-reflect-over-the-members-of-dynamic-object – Alan Tsai Oct 15 '14 at 05:35
  • @AlanTsai I did look at that before I asked this and tried numerous things to get it to work. Each thing I tried, either came up empty or makes the page time out. Can't seem to get it to work with this object, I have no idea why – RealWorldCoder Oct 15 '14 at 05:37
  • Here, checkout this page, I don't understand what I'm supposed to do, but this is the object: https://github.com/kevin-montrose/Jil/blob/master/Jil/DeserializeDynamic/JsonObject.cs – RealWorldCoder Oct 15 '14 at 05:38

1 Answers1

1

Please allow me to note:

Before I get started, if you don't know the members already when you're parsing JSON, you should not be parsing into a dynamic object. The built-in .Net JavaScriptConverter class can parse JSON into a IDictionary<string, object> which would be much better for you.

However, if you still want to use dynamic objects for some reason:

If you want to stick with your current library: I dont know how exactly that class is working, and I'm not saying this is the best solution, but by looking at the source it jumps out to me that you can grab a list of the ObjectMembers keys using reflection.

Type t = typeof(JsonObject)
var fi = t.GetField("ObjectMembers", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
IEnumerable<string> keys = ((Dictionary<string, JsonObject>)fi.GetValue(obj)).Keys;


Edit: Seeing that JsonObject implements IDynamicMetaObjectProvider, the following method mentioned in this question will also work on it:

public static IEnumerable<string> GetMemberNames(object target, bool dynamicOnly = false)
{
    var tList = new List<string>();
    if (!dynamicOnly)
    {
       tList.AddRange(target.GetType().GetProperties().Select(it => it.Name));
    }

    var tTarget = target as IDynamicMetaObjectProvider;
    if (tTarget !=null)
    {
        tList.AddRange(tTarget.GetMetaObject(Expression.Constant(tTarget)).GetDynamicMemberNames());
    }else
    {

        if (ComObjectType != null && ComObjectType.IsInstanceOfType(target) && ComBinder.IsAvailable)
        {
            tList.AddRange(ComBinder.GetDynamicDataMemberNames(target));
        }
    }
    return tList;
} 



If you are open to trying a different JSON converter: try this class here: http://pastie.org/private/vhwfvz0pg06zmjqirtlxa I'm not sure where I found it (I can't take credit) but here is an example of how to use it how you want:

// Create dynamic object from JSON string
dynamic obj = DynamicJsonConverter.CreateSerializer().Deserialize("JSON STRING", typeof(object));
// Get json value
string str = obj.someValue;
// Get list of members
IEnumerable<string> members = (IDictionary<string, object>)obj).Keys

Personally I like using the second one, it is simple and easy to use - and builds off of the built in .Net JSON parser.

caesay
  • 16,932
  • 15
  • 95
  • 160