如何从代码检索数据注释? (编程)
我正在使用System.ComponentModel.DataAnnotations
为我的Entity Framework 4.1项目提供validation。
例如:
public class Player { [Required] [MaxLength(30)] [Display(Name = "Player Name")] public string PlayerName { get; set; } [MaxLength(100)] [Display(Name = "Player Description")] public string PlayerDescription{ get; set; } }
我需要检索Display.Name
注释值,以显示在一个消息,如select“播放器名称”是弗兰克。
================================================== ===============================
另一个为什么我可能需要检索注释的例子:
var playerNameTextBox = new TextBox(); playerNameTextBox.MaxLength = GetAnnotation(myPlayer.PlayerName, MaxLength);
我怎样才能做到这一点?
扩展方法:
public static T GetAttributeFrom<T>(this object instance, string propertyName) where T : Attribute { var attrType = typeof(T); var property = instance.GetType().GetProperty(propertyName); return (T)property .GetCustomAttributes(attrType, false).First(); }
码:
var name = player.GetAttributeFrom<DisplayAttribute>("PlayerDescription").Name; var maxLength = player.GetAttributeFrom<MaxLengthAttribute>("PlayerName").Length;
尝试这个:
((DisplayAttribute) (myPlayer .GetType() .GetProperty("PlayerName") .GetCustomAttributes(typeof(DisplayAttribute),true)[0])).Name;
你想使用reflection来实现这一点。 一个工作解决scheme可以在这里find。
修正了从这里使用MetadataTypeAttribute的元数据类
public T GetAttributeFrom<T>( object instance, string propertyName) where T : Attribute { var attrType = typeof(T); var property = instance.GetType().GetProperty(propertyName); T t = (T)property.GetCustomAttributes(attrType, false).FirstOrDefault(); if (t == null) { MetadataTypeAttribute[] metaAttr = (MetadataTypeAttribute[])instance.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true); if (metaAttr.Length > 0) { foreach (MetadataTypeAttribute attr in metaAttr) { var subType = attr.MetadataClassType; var pi = subType.GetField(propertyName); if (pi != null) { t = (T)pi.GetCustomAttributes(attrType, false).FirstOrDefault(); return t; } } } } else { return t; } return null; }
这是我做了类似的事情
/// <summary> /// Returns the DisplayAttribute of a PropertyInfo (field), if it fails returns null /// </summary> /// <param name="propertyInfo"></param> /// <returns></returns> private static string TryGetDisplayName(PropertyInfo propertyInfo) { string result = null; try { var attrs = propertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true); if (attrs.Any()) result = ((DisplayAttribute)attrs[0]).Name; } catch (Exception) { //eat the exception } return result; }
这里有一些静态方法可以用来获取MaxLength或其他任何属性。
using System; using System.Linq; using System.Reflection; using System.ComponentModel.DataAnnotations; using System.Linq.Expressions; public static class AttributeHelpers { public static Int32 GetMaxLength<T>(Expression<Func<T,string>> propertyExpression) { return GetPropertyAttributeValue<T,string,MaxLengthAttribute,Int32>(propertyExpression,attr => attr.Length); } //Optional Extension method public static Int32 GetMaxLength<T>(this T instance,Expression<Func<T,string>> propertyExpression) { return GetMaxLength<T>(propertyExpression); } //Required generic method to get any property attribute from any class public static TValue GetPropertyAttributeValue<T, TOut, TAttribute, TValue>(Expression<Func<T,TOut>> propertyExpression,Func<TAttribute,TValue> valueSelector) where TAttribute : Attribute { var expression = (MemberExpression)propertyExpression.Body; var propertyInfo = (PropertyInfo)expression.Member; var attr = propertyInfo.GetCustomAttributes(typeof(TAttribute),true).FirstOrDefault() as TAttribute; if (attr==null) { throw new MissingMemberException(typeof(T).Name+"."+propertyInfo.Name,typeof(TAttribute).Name); } return valueSelector(attr); } }
使用静态方法…
var length = AttributeHelpers.GetMaxLength<Player>(x => x.PlayerName);
或者在实例上使用可选的扩展方法…
var player = new Player(); var length = player.GetMaxLength(x => x.PlayerName);
或者使用完整的静态方法的任何其他属性(例如StringLength)…
var length = AttributeHelpers.GetPropertyAttributeValue<Player,string,StringLengthAttribute,Int32>(prop => prop.PlayerName,attr => attr.MaximumLength);