无法通过反射获得动态属性

时间:2014-10-15 05:23:16

标签: c# asp.net

使用我正在使用的Json反序列化组件(Jil)生成动态对象,我可以直接访问属性。但我事先并不知道他们的名字,所以我试图用反思来得名字。我试过这样做:

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

但页面超时。在调试器中没有给我任何东西,只是坐在那里什么都不做,或什么都没有告诉我。

甚至在我这样做时也会发生这种情况:

var t = myDynObj.GetType();

但是当我这样做时,它起作用:

var val = myDynObj.MyStaticValue1

真的无法用它做任何其他事情。 Anyonw知道为什么,以及如何让它工作?

1 个答案:

答案 0 :(得分:1)

请允许我注意:

在开始之前,如果您在解析JSON时已经不知道成员,则不应该解析为动态对象。内置的.Net JavaScriptConverter类可以将JSON解析为IDictionary<string, object>,这对你来说会更好。

但是,如果您仍想出于某种原因使用动态对象:

如果您想坚持使用当前的库:我不知道该课程究竟是如何运作的,我并不是说这是最佳解决方案,而是通过查看来源它跳出来告诉我你可以使用反射来获取ObjectMembers键的列表。

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;


编辑:看到JsonObject实现了IDynamicMetaObjectProvider,此问题中提到的以下方法也适用于它:

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;
} 



如果您愿意尝试使用其他JSON转换器:请在此处尝试此课程:http://pastie.org/private/vhwfvz0pg06zmjqirtlxa我不知道我在哪里找到它(我不能信用)但是这是一个如何使用它的例子:

// 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

我个人喜欢使用第二个,它简单易用 - 并且内置的.Net JSON解析器构建。