93

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?

5
  • 1
    Is something an IDynamicMetaObjectProvider?
    – SLaks
    Commented Dec 25, 2011 at 21:00
  • Check the runtime type of something in the debugger and look at its public members.
    – SLaks
    Commented Dec 26, 2011 at 0:03
  • 1
    Can you check what does d.GetType() give you in runtime? Commented Dec 26, 2011 at 1:29
  • This SO answer shows how to retrieve a dynamic property. Commented Dec 26, 2011 at 3:45
  • possible duplicate of Loop DynamicObject properties
    – nawfal
    Commented Jul 19, 2014 at 20:48

12 Answers 12

129

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:

0
41

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);
}
2
  • 1
    This worked beautifully for me, what i was not able to achieve for dynamic type, thanks Commented Apr 5, 2016 at 13:30
  • 2
    That only works if d is a static type. If D is a IDynamicMetaObjectProvider, (such as a JObject) it will give you the wrong properties. For example, if d = obj, then it won't return 'x', it will return the raw properties on JObject. JObject obj = JObject.FromObject(new { x = 123 });
    – Mike S
    Commented Apr 19, 2017 at 22:51
28

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);
    }
}
2
  • @Ewerton It's been quite a while, but I see it uses System.Linq.Expressions to bind the dynamic getter to a call site, and leaves the compiling to the LambdaExpression. I don't know if I took this from a decompiled code, or somewhere else.
    – IS4
    Commented Sep 29, 2017 at 15:19
  • You are a master!
    – momvart
    Commented Feb 24, 2021 at 18:46
9

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
 }
1
  • 2
    Only if the underlying type is a plain object. It won't work for wrapper objects like PSObject Commented Sep 2, 2018 at 20:31
6
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

5

IF d was created by Newtonsoft you can use this to read property names and values:

    foreach (JProperty property in d)
    {
        DoSomething(property.Name, property.Value);
    }
4

Did you see ExpandoObject class?

Directly from MSDN description: "Represents an object whose members can be dynamically added and removed at run time."

With it you can write code like this:

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");
4
  • The property names are not known so this will not work. Commented Feb 3, 2018 at 17:12
  • The code works (i checked it in visual studio) because the employee instance is an ExpandoObject so it's possibile add and remove property at runtime (how explained into the MS official documentation). This code accomplish the question.
    – ADIMO
    Commented Feb 13, 2018 at 9:39
  • There are other dynamic objects than ExpandoObject, like PSObject. Commented Sep 2, 2018 at 20:31
  • No @ADIMO it doesn't. The question is how to Access the property of an dynamic object. BUT at the moment he doesn't know what are the properties. Those are coming from a string array. So he needs to FIND THE PROPERTY IF IT EXISTS by name and THEN get the value from the property Commented May 19, 2020 at 18:50
3

Getting value data from a dynamic objects using property(string).

var nameOfProperty = "chairs";
var propertyInfo = model.assets.GetType().GetField(nameOfProperty).GetValue(model.assets);
0

I know this is an old Question, but i would like to share my Solution: This works same for both Dynamic and 'non-dynamic' data:

var _RowData = mydata[RowIndex]; //<- Whole Row of Data
//Locate and Load the Field Property by Name:
var propertyInfo = System.ComponentModel.TypeDescriptor.
    GetProperties((object)_RowData ).   
    Find("field_name", true);

string FieldName = propertyInfo.Name;
object FieldValue = propertyInfo.GetValue(_dataRow);

Tested over Dynamic data converted from a JSON file using Newtonsoft.Json.

-1

Thought this might help someone in the future.

If you know the property name already, you can do something like the following:

[HttpPost]
[Route("myRoute")]
public object SomeApiControllerMethod([FromBody] dynamic args){
   var stringValue = args.MyPropertyName.ToString();
   //do something with the string value.  If this is an int, we can int.Parse it, or if it's a string, we can just use it directly.
   //some more code here....
   return stringValue;
}
1
  • The property names are not known. Commented Feb 3, 2018 at 17:10
-1

Say you have anonymous type in service result.Value, with class errorCode and property ErrorMessage, and needed to get the value of ErrorMessage, could get it in one-liner like this using dynamic:

var resVal = (dynamic)result.Value; var errMsg = resVal.GetType().GetProperty("errorCode").GetValue(resVal, null).ErrorMessage;

-4

you can try like this:

d?.property1 , d?.property2

I have tested it and working with .netcore 2.1

1
  • 3
    The question is talking about getting value from from dynamic object, but he has the property name as string ... for instance he want to do something like what we did in Javascript: obj["property1"] and i believe this is not an answer.
    – bunjeeb
    Commented Nov 16, 2019 at 1:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.