Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get metadata custom attributes?

I have a class that defines data annotations at class level. The meta data class has custom attributes associated with it, along with the usual DisplayName, DisplayFormat etc.

public class BaseMetaData
{
    [DisplayName("Id")]
    public object Id { get; set; }

    [DisplayName("Selected")]
    [ExportItem(Exclude = true)]
    public object Selected { get; set; }
}

[MetadataType(typeof(BaseMetaData))]
public class BaseViewModel
{
    public int Id { get; set; }
    public bool Selected { get; set; }

Given a type T, how can I retrieve the custom attributes from the meta data class? The attempt below would not work as the metadata properties are from the BaseViewModel rather than the BaseMetaData class.

Needs to work generically i.e. can't do typeof(BaseMetaData).GetProperty(e.PropertyName). Wondering if there is a way of getting the MetadataType from the class then it would make it possible.

var type = typeof (T);
var metaData = ModelMetadataProviders.Current.GetMetadataForType(null, type);

var propertMetaData = metaData.Properties
    .Where(e =>
    {
        var attribute = type.GetProperty(e.PropertyName)
            .GetCustomAttributes(typeof(ExportItemAttribute), false)
            .FirstOrDefault() as ExportItemAttribute;
        return attribute == null || !attribute.Exclude;
    })
    .ToList();
like image 734
David Avatar asked Jun 02 '14 14:06

David


Video Answer


1 Answers

Found a solution by using the type of MetadataTypeAttribute to get the custom attributes.

var type = typeof (T);
var metadataType = type.GetCustomAttributes(typeof(MetadataTypeAttribute), true)
    .OfType<MetadataTypeAttribute>().FirstOrDefault();
var metaData = (metadataType != null)
    ? ModelMetadataProviders.Current.GetMetadataForType(null, metadataType.MetadataClassType)
    : ModelMetadataProviders.Current.GetMetadataForType(null, type);

var propertMetaData = metaData.Properties
    .Where(e =>
    {
        var attribute = metaData.ModelType.GetProperty(e.PropertyName)
            .GetCustomAttributes(typeof(ExportItemAttribute), false)
            .FirstOrDefault() as ExportItemAttribute;
        return attribute == null || !attribute.Exclude;
    })
    .ToList();
like image 93
David Avatar answered Oct 03 '22 18:10

David