使用我正在使用的Json反序列化组件(Jil
)生成动态对象,我可以直接访问属性。但我事先并不知道他们的名字,所以我试图用反思来得名字。我试过这样做:
var props = myDynObj.GetType().GetProperties();
但页面超时。在调试器中没有给我任何东西,只是坐在那里什么都不做,或什么都没有告诉我。
甚至在我这样做时也会发生这种情况:
var t = myDynObj.GetType();
但是当我这样做时,它起作用:
var val = myDynObj.MyStaticValue1
真的无法用它做任何其他事情。 Anyonw知道为什么,以及如何让它工作?
答案 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解析器构建。