2011-08-11 75 views
36

我正在使用System.ComponentModel.DataAnnotations爲我的實體框架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註釋值顯示在消息如所選擇的「表演者姓名」是弗蘭克。

============================================= ====================================

爲什麼我需要檢索註釋的另一個例子:

var playerNameTextBox = new TextBox(); 
playerNameTextBox.MaxLength = GetAnnotation(myPlayer.PlayerName, MaxLength); 

我該怎麼做?

+0

請看看這個帖子http://stackoverflow.com/questions/803221/c-reflection-finding-attributes-on-a-member-field它顯示你如何使用反射來做到這一點。 – Jethro

回答

70

擴展方法:

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; 
+2

如果我錯了,請糾正我的錯誤,但我認爲如果Player類中存在多個DisplayAttribute(這幾乎總是如此),它將不起作用。在我的問題中查看我更新的代碼。 – asmo

+0

代碼示例已更新。 – jgauffin

+0

如果註釋不存在於屬性上,則會彈出。如果註釋可能不存在,則使用'FirstOrDefault()'而不是'First()' –

0

你想使用反射來實現這一點。可以找到一個工作解決方案here

5

嘗試:

((DisplayAttribute) 
    (myPlayer 
    .GetType() 
    .GetProperty("PlayerName") 
    .GetCustomAttributes(typeof(DisplayAttribute),true)[0])).Name; 
0

here

用於使用元數據類具有MetadataTypeAttribute一個修復
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; 
} 
1

東西下面是一些你可以用它來獲得的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

相關問題