5

I have a ViewModel which has a [key] property and i would like to get that from an instance of that view model.

My code looks something like this (fictional models)

class AddressViewModel
{
    [Key]
    [ScaffoldColumn(false)]
    public int UserID { get; set; } // Foreignkey to UserViewModel
}

// ... somewhere else i do:
var addressModel = new AddressViewModel();
addressModel.HowToGetTheKey..??

So i need to get the UserID(in this case) from the ViewModel. How can i do this?

w00
  • 26,172
  • 30
  • 101
  • 147
  • 1
    You want to use Reflection to walk the properties of the ViewModel instance and query the custom attributes of each `PropertyInfo` to see if `KeyAttribute` exists on it. [This question](http://stackoverflow.com/questions/390594/c-sharp-setting-property-values-through-reflection-with-attributes) covers the topic. – Adam Houldsworth Oct 11 '12 at 09:04
  • 1
    You also need to think about what happens if `KeyAttribute` annotates multiple properties. – Jon Oct 11 '12 at 09:04

3 Answers3

10

If you are stuck or confused with any of the code in the example, just drop a comment and I'll try to help.

In summary, you are interesting in using Reflection to walk the meta-data of the type to get properties that have a given attribute assigned to them.

Below is just one way of doing this (there are many others and also many methods that provide similar functionality).

Taken from this question I linked in the comments:

PropertyInfo[] properties = viewModelInstance.GetType().GetProperties();

foreach (PropertyInfo property in properties)
{
    var attribute = Attribute.GetCustomAttribute(property, typeof(KeyAttribute)) 
        as KeyAttribute;

    if (attribute != null) // This property has a KeyAttribute
    {
         // Do something, to read from the property:
         object val = property.GetValue(viewModelInstance);
    }
}

Like Jon says, handle multiple KeyAttribute declarations to avoid issues. This code also assumes you are decorating public properties (not, non-public properties or fields) and requires System.Reflection.

Community
  • 1
  • 1
Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
2

You can use reflection to achieve this:

       AddressViewModel avm = new AddressViewModel();
       Type t = avm.GetType();
       object value = null;
       PropertyInfo keyProperty= null;
       foreach (PropertyInfo pi in t.GetProperties())
           {
           object[] attrs = pi.GetCustomAttributes(typeof(KeyAttribute), false);
           if (attrs != null && attrs.Length == 1)
               {
               keyProperty = pi;
               break;
               }
           }
       if (keyProperty != null)
           {
           value =  keyProperty.GetValue(avm, null);
           }
Kamil Krasinski
  • 511
  • 4
  • 10
0

To get key and value, you can do this:

PropertyInfo[] properties = reqData.GetType().GetProperties();

foreach (PropertyInfo property in properties)
{
    var key = property.Name
    var value = Convert.ToString(property.GetValue(reqData));
}

Note: reqData => instance of an object

anil shrestha
  • 2,136
  • 2
  • 12
  • 26