views:

74

answers:

2

Hi,

Is it possible to access a parent class from within an attribute.

For example I would like to create a DropDownListAttribute which can be applied to a property of a viewmodel class in MVC and then create a drop down list from an editor template. I am following a similar line as Kazi Manzur Rashid here.

He adds the collection of categories into viewdata and retrieves them using the key supplied to the attribute.

I would like to do something like the below,

public ExampleDropDownViewModel {

   public IEnumerable<SelectListItem> Categories {get;set;}

   [DropDownList("Categories")]
   public int CategoryID { get;set; }
}

The attribute takes the name of the property containing the collection to bind to. I can't figure out how to access a property on the parent class of the attribute. Does anyone know how to do this?

Thanks

+1  A: 

You can do that using reflection. Do the following in your main class:

Type type = typeof(ExampleDropDownViewModel));
// Get properties of your data class
PropertyInfo[] propertyInfo = type.GetProperties( );

foreach( PropertyInfo prop in propertyInfo )
{
   // Fetch custom attributes applied to a property        
   object[] attributes = prop.GetCustomAttributes(true);

   foreach (Attribute attribute in attributes) {
      // we are only interested in DropDownList Attributes..
      if (attribute is DropDownListAttribute) {
    DropDownListAttribute dropdownAttrib = (DropDownListAttribute)attribute;
         Console.WriteLine("table set in attribute: " + dropdownAttrib.myTable);
      }
   }
}
Sander Pham
Thanks for the reply. Where would this code actually go? I can't see how to integrate this into the metadataprovider suggested by Kazi. Also you do not appear to be reflecting over an instance so how would you get the collection from the Categories property.
madcapnmckay
Please note that a custom attribute is a decorator for your object and its info is added to the metadata of the objects generated by the compiler. So basically, when you decorate a category property with your DropDownList attribute, you could determine during rendering of the template if it should be rendered as a dropdown list or not.
Sander Pham
+1  A: 

You can't access a parent type from an attribute. Attributes are metadata that is applied to a type, but you can't look back and try and identify the type, unless you did something like:

[MyCustomAttribute(typeof(MyClass))]
public class MyClass {
  ///
}

With the reflection solution above, you are not actually achieving the action of getting a type from an attribute, you are doing the reverse, you are getting attributes from a type. At this point, you already have the type.

Matthew Abbott