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.