我正在使用System.ComponentModel.DataAnnotations
为我的Entity Framework 4.1项目提供验证。
例如:
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
注释值以在消息中显示它,例如所选的“玩家名称”是Frank。
=============================================== ==================================
我需要检索注释的另一个例子:
var playerNameTextBox = new TextBox();
playerNameTextBox.MaxLength = GetAnnotation(myPlayer.PlayerName, MaxLength);
我该怎么做?
答案 0 :(得分:78)
扩展方法:
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;
答案 1 :(得分:6)
试试这个:
((DisplayAttribute)
(myPlayer
.GetType()
.GetProperty("PlayerName")
.GetCustomAttributes(typeof(DisplayAttribute),true)[0])).Name;
答案 2 :(得分:3)
以下是一些静态方法,可用于获取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);
灵感来自这里的答案...... https://stackoverflow.com/a/32501356/324479
答案 3 :(得分:0)
您希望使用Reflection来实现此目的。可以找到工作解决方案here。
答案 4 :(得分:0)
使用元数据类与here
中的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;
}
答案 5 :(得分:0)
这就是我做类似的事情
/// <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;
}
答案 6 :(得分:0)
由于https://stackoverflow.com/a/7027791/7173655上的受接受者答案仍然使用魔术常数,因此我基于链接的答案共享我的代码:
扩展方法:
localStorage
在没有魔术常数的情况下使用(确保重构的伤害较小):
public static TA GetAttributeFrom<TC,TA>(string propertyName) where TA : Attribute {
return (TA)typeof(TC).GetProperty(propertyName)
.GetCustomAttributes(typeof(TA), false).SingleOrDefault();
}
答案 7 :(得分:0)
我认为这个示例https://github.com/TeteStorm/DataAnnotationScan可能非常有用。
我只是想在模型装配中获得EF使用的数据注释,但是可以随意进行分叉和更改。
更改以下方法HasEFDataAnnotaion并玩得开心!
https://github.com/TeteStorm/DataAnnotationScan
private static bool HasEFDataAnnotaion(PropertyInfo[] properties)
{
return properties.ToList().Any((property) =>
{
var attributes = property.GetCustomAttributes(false);
Attribute[] attrs = System.Attribute.GetCustomAttributes(property);
return attrs.Any((attr) =>
{
return attr is KeyAttribute || attr is ForeignKeyAttribute || attr is IndexAttribute || attr is RequiredAttribute || attr is TimestampAttribute
|| attr is ConcurrencyCheckAttribute || attr is MinLengthAttribute || attr is MinLengthAttribute
|| attr is MaxLengthAttribute || attr is StringLengthAttribute || attr is TableAttribute || attr is ColumnAttribute
|| attr is DatabaseGeneratedAttribute || attr is ComplexTypeAttribute;
});
});
}