2010-03-02 16 views
5

Estoy tratando de usar la reflexión para verificar si las propiedades en una clase dada tienen un atributo ReadOnly establecido. Las clases que estoy usando son MVC Visualización de modelos (usando una clase parcial "amigo" de los metadatos.C# Buddy Classes/Metadatos y reflexión

public partial class AccountViewModel 
{ 
    public virtual Int32 ID { get; set; } 
    public virtual decimal Balance { get; set; }  

} 
[MetadataType(typeof(AccountViewModelMetaData))] 
public partial class AccountViewModel 
{ 
    class AccountViewModelMetaData 
    { 
     [DisplayName("ID")] 
     public virtual Int32 ID { get; set; } 

     [DisplayName("Balance")] 
     [DataType(DataType.Currency)] 
     [ReadOnly(true)] 
     public virtual decimal Balance { get; set; } 

    } 
} 

Quiero comprobar si el "equilibrio" tiene la propiedad de sólo lectura. Si puedo configurar el atributo de sólo lectura en la balanza propiedad de AccountViewModel, i puede recuperar de esta manera:.?

Type t = typeof(AccountViewModel); 
PropertyInfo pi = t.GetProperty("Balance"); 
bool isReadOnly = ReadOnlyAttribute.IsDefined(pi,typeof(ReadOnlyAttribute); 

que no puede recuperar la información de atributo si está en la clase de metadatos ¿Cómo puedo comprobar si existe el atributo he definido clases de metadatos para todos mis modelos de vista, y necesito una forma genérica para verificar los atributos en las clases de metadatos.

¿Alguna sugerencia?

Respuesta

1

A continuación, un ejemplo breve pero funcional, tenga en cuenta que hice la clase anidada internal para que sea visible desde el exterior.

public partial class AccountViewModel 
{ 
    internal class AccountViewModelMetaData 
    { 
     public virtual Int32 ID { get; set; } 
     [ReadOnlyAttribute(false)] 
     public virtual decimal Balance { get; set; } 
    } 

    public virtual Int32 ID { get; set; } 
    public virtual decimal Balance { get; set; } 
} 
class Program 
{ 
    public static void Main(string[] args) 
    { 
     Type metaClass = typeof(AccountViewModel.AccountViewModelMetaData); 

     bool hasReadOnlyAtt = HasReadOnlyAttribute(metaClass, "Balance"); 

     Console.WriteLine(hasReadOnlyAtt); 
    } 

    private static bool HasReadOnlyAttribute(Type type, string property) 
    { 
     PropertyInfo pi = type.GetProperty(property); 

     return ReadOnlyAttribute.IsDefined(pi, typeof(ReadOnlyAttribute)); 
    } 
} 

También tenga en cuenta que esto comprueba la existencia del atributo. Puede, en este ejemplo, especificar el atributo pero proporcionar el valor de false. Si desea verificar si la propiedad es de solo lectura o no, no solo puede usar el método ReadOnlyAttribute.IsDefined.

7

la solución es utilizar GetCustomAttributes para obtener tipos de metadatos y comprobar las propiedades de esos también ...

Type t = typeof(MyClass); 
PropertyInfo pi = t.GetProperty(PropertyName); 
bool isReadOnly = ReadOnlyAttribute.IsDefined(pi, typeof(ReadOnlyAttribute)); 

if (!isReadOnly) 
{ 
    //check for meta data class. 
    MetadataTypeAttribute[] metaAttr = (MetadataTypeAttribute[])t.GetCustomAttributes(typeof(MetadataTypeAttribute),true); 

    if (metaAttr.Length > 0) 
    { 
     foreach (MetadataTypeAttribute attr in metaAttr) 
     { 
      t = attr.MetadataClassType; 
      pi = t.GetProperty(PropertyName); 

      if (pi != null) isReadOnly = ReadOnlyAttribute.IsDefined(pi, typeof(ReadOnlyAttribute)); 

      if (isReadOnly) break; 
     } 
    } 
} 
+1

Mira que está comprobando que existe el atributo y no es que se define ha 'verdadera '. ¿Ha considerado lo que sucede si la propiedad está definida tiene '[ReadOnlyAttribute (false)]'? –

+1

Lo siento, pero no pude entender su solución. :( – Rohit

Cuestiones relacionadas