Wednesday, April 18, 2012

Get model attribute value from Controller using Reflection

C# is a nice language with those attribute decorations. You can create your own attributes and check their values for your test or for other purposes.

In MVC models, .NET framework provides data model validation attributes which inherit from Attribute class. You can get those attributes for your properties. Here is an example i just answered at stackoverflow.

We have Name property with DisplayName attribute which has public get property with "DisplayName" attribute.


public class MailJobView
    {
      

        public int MailJobId { getset; }
 
        [DisplayName("Job Name")]
        [StringLength(50)]
        public string Name { getset; }
}
public void TestAttribute()
    {
        MailJobView view = new MailJobView();
        string displayname = view.Attributes<DisplayNameAttribute>("Name") ;


    }
If you have one simple extension method, you can see the display name easily. Here, i am passing attribute type and property name for this object. You can do in a different way if you want, but reflection calls will be similar. This extension method will follow convention and lookup property in that attribute class. Property name will be class name with "Attribute" removed. If you want, you can remove constraint for inheriting from attribute class.


public static class AttributeSniff
{
    public static string Attributes<T>(this object inputobject, string propertyname) where T : Attribute
    {
        //each attribute can have different internal properties
        //DisplayNameAttribute has  public virtual string DisplayName{get;}
        Type objtype = inputobject.GetType();
        PropertyInfo propertyInfo = objtype.GetProperty(propertyname);
        if (propertyInfo != null)
        {
            object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(T), true);

            // take only publics and return first attribute
            if (propertyInfo.CanRead && customAttributes.Count() > 0)
            {
                //get that first one for now

                Type ourFirstAttribute = customAttributes[0].GetType();
                //Assuming your attribute will have public field with its name
                //DisplayNameAttribute will have DisplayName property
                PropertyInfo defaultAttributeProperty = ourFirstAttribute.GetProperty(ourFirstAttribute.Name.Replace("Attribute",""));
                if (defaultAttributeProperty != null)
                {
                    object obj1Value = defaultAttributeProperty.GetValue(customAttributes[0], null);
                    if (obj1Value != null)
                    {
                        return obj1Value.ToString();
                    }
                }

            }

        }

        return null;
    }
}

No comments:

Post a Comment

Hey!
Let me know what you think?