We help IT Professionals succeed at work.

C# - Get value of property from an object dynamically

Grant Surridge
on
Hi

I have a class called "shipment" that contains a lot of properties, such as Address1, Address2, Address3, PostCode, OrderNumber etc etc etc. This object gets passed to a web service, it creates the orders, then it sends an email. However, I want to make the email dynamic. For instance: for customer A, I might want to show Address1 and Address2, Customer B might want to show OrderNumber and Post Code

What I want to do, is have a database table that is called, and then says which properties of the object need to go onto the email. I think I need to use reflection, but I don't really understand it

So, in the db table will be a value of shipment.Address1 and shipment.Address2 which will be pulled out as strings, that then needs converting to take the value of the actual shipment.Address1 and 2

Does this make sense ? Hopefully have explained myself ok !

Thanks in advance
Comment
Watch Question

High School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009
Commented:
This example shows how to get both a public field and a public property:
    public class shipment
    {

        public string Address1;

        private string _Address2;
        public string Address2
        {
            get { return _Address2; }
            set { _Address2 = value;  }
        }

    }

Open in new window


            shipment s = new shipment();
            s.Address1 = "Hello";
            s.Address2 = "World";

            string field = "Address1";
            System.Reflection.FieldInfo fi = s.GetType().GetField(field, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
            if (fi != null)
            {
                string value = fi.GetValue(s).ToString();
                MessageBox.Show(field + " = " + value);
            }

            string propName = "Address2";
            System.Reflection.PropertyInfo pi = s.GetType().GetProperty(propName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
            if (pi != null)
            {
                string value = pi.GetValue(s, null).ToString();
                MessageBox.Show(propName + " = " + value);
            }

Open in new window

Grant SurridgeIT Controller

Author

Commented:
perfect - thank you so much
Grant SurridgeIT Controller

Author

Commented:
Hi

I need to develop this a little more (will open a new question if you wish)

I have used your code as follows:

                                string propName = field;
                                System.Reflection.PropertyInfo pi = order.Header.GetType().GetProperty(propName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
                                if (pi != null)
                                {
                                    string value = pi.GetValue(order.Header, null).ToString();
                                    //Console.WriteLine(propName + " = " + value);
                                    strEmailLine += value + "~";
                                }

Open in new window



I have the code inside a loop:

            foreach (Order order1 in file.Orders)

and then using some code I used before, I tried

Type type = Type.GetType("order1.Header"); - but this resolves to null

If I tried and use the full path Integration.Types.Order then it works, but this won't relate specifically to the instance of ORder1 inside the loop

Does this make sense ?

Thanks
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009

Commented:
Are you trying to get the type of "order1", or "Header"?

At any rate, use GetType() against that specific member like this:

    Type type = order1.GetType();

or this:

    Type type = order1.Header.GetType();
Grant SurridgeIT Controller

Author

Commented:
Hi

Am trying to get it for both. The problem is that I need to do it dynamically, so order1 or order1.Header will actually be a string value. If I do the below, type is null, which implies it can't find order1.Header when passed as a string

            foreach (Order order1 in file.Orders)
            {

                string propName = "SHIPMENT_ID";
                Type type = Type.GetType("Order1.Header");
                System.Reflection.PropertyInfo pi = type.GetType().GetProperty(propName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
                if (pi != null)
                {
                    string value = pi.GetValue(order.Header, null).ToString();
                    Console.WriteLine(value);
                }


            }

Open in new window

Grant SurridgeIT Controller

Author

Commented:
Hi

In the above example, where i have done Type.GetType("Order1.Header") - this is a mistake, it should be all lower case, and that still doesn't work

Scott
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
CERTIFIED EXPERT
Top Expert 2009

Commented:
Is "Header" an actual TYPE (class/structure), or is it simply the name of a field/property?

I'm thinking the latter.  If this is the case then you'd have to PARSE your string to separate into the Type portion and the FIELD portion.  To get a type from a string, though, I think you'd need the entire FULLY QUALIFIED name like:

    Type T = Type.GetType("WindowsFormsApplication1.Order");

Afterwards, you'd use GetField() or GetProperty(), and pass them "Header" as I demonstrated earlier.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.