I am trying to use reflection to check if properties on a given class have a ReadOnly attribute set. The classes I am using are MVC View Models (using a partial "buddy" class for the metadata.
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; }
}
}
I want to check if "Balance" has the ReadOnly property. If i set the ReadOnly attribute on the Balance property of AccountViewModel, i can retrieve it this way:
Type t = typeof(AccountViewModel);
PropertyInfo pi = t.GetProperty("Balance");
bool isReadOnly = ReadOnlyAttribute.IsDefined(pi,typeof( ReadOnlyAttribute);
I can't retrieve the attribute info if it is on the meta data class. How can i check if the attribute exists? I have meta data classes defined for all my view models, and need a generic way to check for attributes on meta data classes.
Any suggestions?
the solution is to use GetCustomAttributes
to get MetaData types and check the properties on those as well...
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;
}
}
}
A short but working example follows, note that I made the nested class internal
in order to be visible to the outside.
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));
}
}
Also be aware that this checks for the existence of the attribute. You can has in this example specify the attribute but provide the value of false
. If you want to check if the property is read-only or not, you can't only use the method ReadOnlyAttribute.IsDefined
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With