Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get [key] property from ViewModel

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?

like image 343
w00 Avatar asked Oct 11 '12 09:10

w00


2 Answers

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);
           }
like image 30
Kamil Krasinski Avatar answered Nov 08 '22 19:11

Kamil Krasinski


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.

like image 137
Adam Houldsworth Avatar answered Nov 08 '22 19:11

Adam Houldsworth