简体   繁体   中英

Looping into custom attributes in class Metadata (to avoid modifying auto-generated class by Entity FrameWork diagram)

I made my project using Entity Framework diagram, it created the database and also the model classes. Since I can't modify that class from auto-generated file (well I can, but if I modify the diagram all changes are lost) and I want to use data annotations, I created a metadata class. In the metadata class I can add the data annotations, but the problem is, if I add a custom attribute, when I loop into custom attributes for the property it doesn't show up, it does work if I add the custom attribute in the class in the auto generated file. I just want to add all the class properties that have the [Filtrable] custom attribute in a list.

The autogenerated class:

public partial class Persona
{
    public Persona()
    {
        this.ActividadRegistro = new HashSet<ActividadRegistro>();
    }

    public int Id { get; set; }
    public string Nombre { get; set; }
    public string Direccion { get; set; }
    public string Telefono { get; set; }
    public Sexo Sexo { get; set; }
    public System.DateTime Registro { get; set; }

    public virtual ICollection<ActividadRegistro> ActividadRegistro { get; set; }
}

The metadata class:

[MetadataType(typeof(PersonaMetaData))]
public partial class Persona
{
}

public class PersonaMetaData
{
    [Key]
    public int Id;

    [Filtrable] //Custom attribute to "tag" the property to be included in an array
    [Display(Name = "Nombre")]
    [Required(ErrorMessage = "El nombre es requerido")]
    [StringLength(100)] 
    public string Nombre;

    [Filtrable]
    [Display(Name = "Dirección")]
    [Required(ErrorMessage = "La dirección es requerida")]
    [StringLength(200)] 
    public string Direccion;

    [Display(Name = "Teléfono")]
    [Required(ErrorMessage = "El teléfono es requerido")]
    [StringLength(100)]
    public string Telefono;

    [Display(Name = "Sexo")]
    [Required(ErrorMessage = "El sexo es requerido")]
    public Sexo Sexo;

    [Display(Name = "Registro")]
    [Required(ErrorMessage = "La fecha de registro es requerida")]
    [DataType(DataType.Date)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
    public DateTime Registro;
}

The custom attribute:

[AttributeUsage(AttributeTargets.All)]
public class Filtrable : Attribute, IMetadataAware
{
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.DisplayName = metadata.GetDisplayName() + " (Propiedad que puede ser filtrado)";
        metadata.AdditionalValues["Filtrable"] = true;
    }
}

The not working loop.

        PropertyInfo[] properties = typeof(Persona).GetProperties();
    ArrayList propertiesThatCanBeFiltered = new ArrayList();
    foreach (var property in properties)
    {
        Object[] attributes = property.GetCustomAttributes(typeof(true));
        foreach (var attribute in attributes)
        {
            if (attribute is Filtrable)
            {
                //It never reachs here ! but if I add the [Filtrable] tag at a property in the 
                //auto-generated class it will work.
                propertiesThatCanBeFiltered.Add(property.Name); 
            }
        }
    }

The solution:

    Persona persona = new Persona();
    ArrayList propertiesThatCanBeFiltered = new ArrayList();
    var metaDatas = ModelMetadataProviders.Current.GetMetadataForProperties(persona, persona.GetType());
    foreach (var metaData in metaDatas)
    {
        if (metaData.AdditionalValues.ContainsKey("Filtrable"))
            propertiesThatCanBeFiltered.Add(metaData.PropertyName);
    }

Ok, I solved this issue using GetMetadataForPropierties:

        Persona persona = new Persona();
        ArrayList propertiesThatCanBeFiltered = new ArrayList();
        var metaDatas = ModelMetadataProviders.Current.GetMetadataForProperties(persona, persona.GetType());
        foreach (var metaData in metaDatas)
        {
            if (metaData.AdditionalValues.ContainsKey("Filtrable"))
                propertiesThatCanBeFiltered.Add(metaData.PropertyName);
        }

I hope this help someone

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM