Los metadatos no se cargaron usando MetadataType

Tengo un problema / pregunta sobre MetadataType . Tengo DLL helper-project para acceso a datos desde MS SQL Server usando LinqToSQL. También necesito agregar metadatos para una clase generada ClientInfoView. Lo he hecho de la siguiente manera:

using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel; namespace DataAPI.LINQToSQL { [MetadataType(typeof(ClientInfoViewMetaData))] public partial class ClientInfoView { internal sealed class ClientInfoViewMetaData { [Category("Main Data"), DisplayName("Client ID")] public int ID { get; set; } [Category("Main Data"), DisplayName("Login")] public string Login { get; set; } ... } } } 

Pero cuando revisé los atributos en tiempo de ejecución, descubrí que ClientInfoView no tiene ningún atributo.

¿Puedes ayudarme a encontrar un error?

Para dar una parte de la respuesta, puede verificar que ClientInfoView tenga atributos. Una pequeña demostración que funcionó para mí. Todavía estoy tratando de encontrar por qué no puedo acceder a esos atributos en las propiedades individuales de ClientInfoViewMetaData

  static void Main(string[] args) { TypeDescriptor.AddProviderTransparent( new AssociatedMetadataTypeTypeDescriptionProvider(typeof(ClientInfoView), typeof(ClientInfoViewMetaData)), typeof(ClientInfoView)); ClientInfoView cv1 = new ClientInfoView() { ID = 1 }; var df = cv1.GetType().GetCustomAttributes(true); var dfd = cv1.ID.GetType().GetCustomAttributes(typeof(DisplayNameAttribute), true); var context = new ValidationContext(cv1, null, null); var results = new List(); var isValid = Validator.TryValidateObject( cv1,context, results, true); } } [MetadataType(typeof(ClientInfoViewMetaData))] public partial class ClientInfoView { public int ID { get; set; } public string Login { get; set; } } public class ClientInfoViewMetaData { [Required] [Category("Main Data"), DisplayName("Client ID")] public int ID { get; set; } [Required] [Category("Main Data"), DisplayName("Login")] public string Login { get; set; } } 

porque el metadatatype no es para tales propósitos pero puedes usar este método

 private bool PropertyHasAttribute(string properyName, Type attributeType) { MetadataTypeAttribute att = (MetadataTypeAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(MetadataTypeAttribute)); if (att != null) { ; foreach (var prop in Type.GetType(att.MetadataClassType.UnderlyingSystemType.FullName).GetProperties()) { if (properyName.ToLower() == properyName.ToLower() && Attribute.IsDefined(prop,attributeType)) return true; } } return false; } 

y puedes usar así

 bool res = PropertyHasAttribute("Login", typeof(DisplayAttribute)) 

esto le indica que el inicio de sesión de la propiedad de clase tiene o no tiene atributo de visualización, pero si necesita encontrar el valor de atributo puede usar el método Attribute.GetCustomAttribute y convertirlo en su atributo seleccionado como atributo de visualización y leer la propiedad Name por .Name 🙂

O puede usar este método de extensión basado en la respuesta de elia07:

  Public Function HasAttribute(Of TABLEENTITY, ATTRTYPE)(md As ModelMetadata) As Boolean Dim properyName As String = md.ContainerType.GetProperty(md.PropertyName).ToString() Dim att As MetadataTypeAttribute = DirectCast(Attribute.GetCustomAttribute(GetType(TABLEENTITY), GetType(MetadataTypeAttribute)), MetadataTypeAttribute) If att IsNot Nothing Then For Each prop In Type.[GetType](att.MetadataClassType.UnderlyingSystemType.FullName).GetProperties() If properyName.ToLower() = properyName.ToLower() AndAlso Attribute.IsDefined(prop, GetType(ATTRTYPE)) Then Return True End If Next End If Return False End Function 

Una muestra:

  Dim md As ModelMetadata = ... Dim isReadOnly As Boolean = md.HasAttribute(Of Cikkek, ReadOnlyFW)