Get property value from C# dynamic object by string (reflection?)
Imagine that I have a dynamic variable:
dynamic d = *something*
Now, I create properties for d
which I have on the other hand from a string array:
string[] strarray = { 'property1','property2',..... }
I don't know the property names in advance.
How in code, once d
is created and strarray is pulled from DB, can I get the values?
I want to get d.property1 , d.property2
.
I see that the object has a _dictionary
internal dictionary that contains the keys and the values, how do I retrieve them?
I don't know if there's a more elegant way with dynamically created objects, but using plain old reflection should work:
var nameOfProperty = "property1";
var propertyInfo = myObject.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(myObject, null);
GetProperty
will return null
if the type of myObject
does not contain a public property with this name.
EDIT: If the object is not a "regular" object but something implementing IDynamicMetaObjectProvider
, this approach will not work. Please have a look at this question instead:
- How do I reflect over the members of dynamic object?
This will give you all property names and values defined in your dynamic variable.
dynamic d = { // your code };
object o = d;
string[] propertyNames = o.GetType().GetProperties().Select(p => p.Name).ToArray();
foreach (var prop in propertyNames)
{
object propValue = o.GetType().GetProperty(prop).GetValue(o, null);
}
Hope this would help you:
public static object GetProperty(object o, string member)
{
if(o == null) throw new ArgumentNullException("o");
if(member == null) throw new ArgumentNullException("member");
Type scope = o.GetType();
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
if(provider != null)
{
ParameterExpression param = Expression.Parameter(typeof(object));
DynamicMetaObject mobj = provider.GetMetaObject(param);
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[]{CSharpArgumentInfo.Create(0, null)});
DynamicMetaObject ret = mobj.BindGetMember(binder);
BlockExpression final = Expression.Block(
Expression.Label(CallSiteBinder.UpdateLabel),
ret.Expression
);
LambdaExpression lambda = Expression.Lambda(final, param);
Delegate del = lambda.Compile();
return del.DynamicInvoke(o);
}else{
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
}
}
Use the following code to get Name and Value of a dynamic object's property.
dynamic d = new { Property1= "Value1", Property2= "Value2"};
var properties = d.GetType().GetProperties();
foreach (var property in properties)
{
var PropertyName=property.Name;
//You get "Property1" as a result
var PropetyValue=d.GetType().GetProperty(property.Name).GetValue(d, null);
//You get "Value1" as a result
// you can use the PropertyName and Value here
}
string json = w.JSON;
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
DynamicJsonConverter.DynamicJsonObject obj =
(DynamicJsonConverter.DynamicJsonObject)serializer.Deserialize(json, typeof(object));
Now obj._Dictionary
contains a dictionary. Perfect!
This code must be used in conjunction with Deserialize JSON into C# dynamic object? + make the _dictionary variable from "private readonly" to public in the code there