DisplayName 속성 값 가져 오기
public class Class1
{
[DisplayName("Something To Name")]
public virtual string Name { get; set; }
}
C #에서 DisplayName 특성 값을 얻는 방법은 무엇입니까?
내 유틸리티 방법을 시도하십시오.
using System.ComponentModel;
using System.Globalization;
using System.Linq;
public static T GetAttribute<T>(this MemberInfo member, bool isRequired)
where T : Attribute
{
var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault();
if (attribute == null && isRequired)
{
throw new ArgumentException(
string.Format(
CultureInfo.InvariantCulture,
"The {0} attribute must be defined on member {1}",
typeof(T).Name,
member.Name));
}
return (T)attribute;
}
public static string GetPropertyDisplayName<T>(Expression<Func<T, object>> propertyExpression)
{
var memberInfo = GetPropertyInformation(propertyExpression.Body);
if (memberInfo == null)
{
throw new ArgumentException(
"No property reference expression was found.",
"propertyExpression");
}
var attr = memberInfo.GetAttribute<DisplayNameAttribute>(false);
if (attr == null)
{
return memberInfo.Name;
}
return attr.DisplayName;
}
public static MemberInfo GetPropertyInformation(Expression propertyExpression)
{
Debug.Assert(propertyExpression != null, "propertyExpression != null");
MemberExpression memberExpr = propertyExpression as MemberExpression;
if (memberExpr == null)
{
UnaryExpression unaryExpr = propertyExpression as UnaryExpression;
if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert)
{
memberExpr = unaryExpr.Operand as MemberExpression;
}
}
if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property)
{
return memberExpr.Member;
}
return null;
}
사용법은 다음과 같습니다.
string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty);
당신은하는 데 필요한 PropertyInfo
재산으로 (예를 통해 관련된 typeof(Class1).GetProperty("Name")
) 다음 호출 GetCustomAttributes
.
여러 값을 반환하기 때문에 약간 지저분합니다. 필요한 경우 몇 군데에서이를 수행하는 도우미 메서드를 작성하는 것이 좋습니다. (프레임 워크 어딘가에 이미 도우미 메서드가있을 수 있지만있는 경우에는 알 수 없습니다.)
편집 : leppie가 지적했듯이, 거기 이다 그런 방법 :Attribute.GetCustomAttribute(MemberInfo, Type)
먼저 MemberInfo
해당 속성을 나타내는 개체를 가져와야합니다. 당신은 어떤 형태의 반성을해야 할 것입니다 :
MemberInfo property = typeof(Class1).GetProperty("Name");
(저는 "이전 스타일"리플렉션을 사용하고 있지만 컴파일 타임에 유형에 액세스 할 수있는 경우 표현식 트리를 사용할 수도 있습니다.)
그런 다음 속성을 가져오고 속성 값을 가져올 수 있습니다 DisplayName
.
var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute), true)
.Cast<DisplayNameAttribute>().Single();
string displayName = attribute.DisplayName;
() 괄호는 필수 입력 오류입니다.
강력한 형식의 뷰 모델이므로 Class1이있는 뷰 내에서 :
ModelMetadata.FromLambdaExpression<Class1, string>(x => x.Name, ViewData).DisplayName;
다음 과 같이 DisplayAttribute 및 ResourceType 을 사용하여 속성에서 지역화 된 문자열을 가져 오는 데 관심이있는 사람이있는 경우 :
[Display(Name = "Year", ResourceType = typeof(ArrivalsResource))]
public int Year { get; set; }
뒤에 다음을 사용하십시오 displayAttribute != null
(위에서 @alex의 답변으로 표시됨).
ResourceManager resourceManager = new ResourceManager(displayAttribute.ResourceType);
var entry = resourceManager.GetResourceSet(Thread.CurrentThread.CurrentUICulture, true, true)
.OfType<DictionaryEntry>()
.FirstOrDefault(p => p.Key.ToString() == displayAttribute.Name);
return entry.Value.ToString();
Rich Tebb의 멋진 수업! DisplayAttribute를 사용해 왔지만 코드가 작동하지 않았습니다. 내가 추가 한 유일한 것은 DisplayAttribute 처리입니다. 간략한 검색 결과이 속성은 MVC3 및 .Net 4의 새로운 기능이며 거의 동일한 기능을 더하는 것으로 나타났습니다. 다음은 메서드의 수정 된 버전입니다.
public static string GetPropertyDisplayString<T>(Expression<Func<T, object>> propertyExpression)
{
var memberInfo = GetPropertyInformation(propertyExpression.Body);
if (memberInfo == null)
{
throw new ArgumentException(
"No property reference expression was found.",
"propertyExpression");
}
var displayAttribute = memberInfo.GetAttribute<DisplayAttribute>(false);
if (displayAttribute != null)
{
return displayAttribute.Name;
}
else
{
var displayNameAttribute = memberInfo.GetAttribute<DisplayNameAttribute>(false);
if (displayNameAttribute != null)
{
return displayNameAttribute.DisplayName;
}
else
{
return memberInfo.Name;
}
}
}
var propInfo = new Class1().GetType().GetProperty("Name");
var displayNameAttribute = propInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false);
var displayName = displayNameAttribute[0] as DisplayNameAttribute).DisplayName;
displayName
변수는 이제 속성의 값을 보유합니다.
이 일반적인 유틸리티 방법이 있습니다. 주어진 유형의 목록 (지원 클래스가 있다고 가정)을 전달하고 속성이있는 데이터 테이블을 열 머리글로, 목록 항목을 데이터로 생성합니다.
표준 MVC와 마찬가지로 DisplayName 속성이 정의되어 있지 않으면 속성 이름으로 대체되므로 속성 이름과 다른 DisplayName 만 포함하면됩니다.
public DataTable BuildDataTable<T>(IList<T> data)
{
//Get properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
//.Where(p => !p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal).ToArray(); //Hides virtual properties
//Get column headers
bool isDisplayNameAttributeDefined = false;
string[] headers = new string[Props.Length];
int colCount = 0;
foreach (PropertyInfo prop in Props)
{
isDisplayNameAttributeDefined = Attribute.IsDefined(prop, typeof(DisplayNameAttribute));
if (isDisplayNameAttributeDefined)
{
DisplayNameAttribute dna = (DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute));
if (dna != null)
headers[colCount] = dna.DisplayName;
}
else
headers[colCount] = prop.Name;
colCount++;
isDisplayNameAttributeDefined = false;
}
DataTable dataTable = new DataTable(typeof(T).Name);
//Add column headers to datatable
foreach (var header in headers)
dataTable.Columns.Add(header);
dataTable.Rows.Add(headers);
//Add datalist to datatable
foreach (T item in data)
{
object[] values = new object[Props.Length];
for (int col = 0; col < Props.Length; col++)
values[col] = Props[col].GetValue(item, null);
dataTable.Rows.Add(values);
}
return dataTable;
}
If there's a more efficient / safer way of doing this, I'd appreicate any feedback. The commented //Where clause will filter out virtual properties. Useful if you are using model classes directly as EF puts in "Navigation" properties as virtual. However it will also filter out any of your own virtual properties if you choose to extend such classes. For this reason, I prefer to make a ViewModel and decorate it with only the needed properties and display name attributes as required, then make a list of them.
Hope this helps.
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(foo);
foreach (PropertyDescriptor property in properties)
{
if (property.Name == "Name")
{
Console.WriteLine(property.DisplayName); // Something To Name
}
}
where foo
is an instance of Class1
Assuming property
as PropertyInfo
type, you can do this in one single line:
property.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().Single().DisplayName
Try this code:
EnumEntity.item.GetType().GetFields()[(int)EnumEntity.item].CustomAttributes.ToArray()[0].NamedArguments[0].TypedValue.ToString()
It will give you the value of data attribute Name
.
Please try below code, I think this will solve your problem.
var classObj = new Class1();
classObj.Name => "StackOverflow";
var property = new Class1().GetType().GetProperty(nameof(classObj.Name));
var displayNameAttributeValue = (property ?? throw new InvalidOperationException())
.GetCustomAttributes(typeof(DisplayNameAttribute)) as DisplayNameAttribute;
if (displayNameAttributeValue != null)
{
Console.WriteLine("{0} = {1}", displayNameAttributeValue, classObj.Name);
}
Following Rich Tebb's and Matt Baker's answer, I wanted to use the ReflectionExtensions
methods in a LINQ query, but it didn't work, so I've made this method for it to work.
If DisplayNameAttribute
is set the method will return it, otherwise it will return the MemberInfo
name.
Test method:
static void Main(string[] args)
{
var lst = new List<Test>();
lst.Add(new Test("coucou1", "kiki1"));
lst.Add(new Test("coucou2", "kiki2"));
lst.Add(new Test("coucou3", "kiki3"));
lst.Add(new Test("coucou4", "kiki4"));
lst.ForEach(i =>
Console.WriteLine(i.GetAttributeName<Test>(t => t.Name) + ";" + i.GetAttributeName<Test>(t=>t.t2)));
}
Test method output:
The class with DisplayName1
Attribute:
public class Test
{
public Test() { }
public Test(string name, string T2)
{
Name = name;
t2 = T2;
}
[DisplayName("toto")]
public string Name { get; set; }
public string t2 { get; set; }
}
And the extension method:
public static string GetAttributeName<T>(this T itm, Expression<Func<T, object>> propertyExpression)
{
var memberInfo = GetPropertyInformation(propertyExpression.Body);
if (memberInfo == null)
{
throw new ArgumentException(
"No property reference expression was found.",
"propertyExpression");
}
var pi = typeof(T).GetProperty(memberInfo.Name);
var ret = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault();
return ret != null ? ret.DisplayName : pi.Name;
}
참고URL : https://stackoverflow.com/questions/5015830/get-the-value-of-displayname-attribute
'program story' 카테고리의 다른 글
단어 목록을 만들기 위해 모든 공백을 줄 바꿈 / 단락 표시로 바꿉니다. (0) | 2020.11.26 |
---|---|
Vim의 내용이 아닌 HTML 태그를 삭제하는 방법 (0) | 2020.11.26 |
bash에서 변수의 줄 수를 어떻게 계산합니까? (0) | 2020.11.26 |
C #의 DateTime에서 날짜 부분 추출 (0) | 2020.11.26 |
Jade에서 인라인 요소를 만드는 간결한 방법은 무엇입니까? (0) | 2020.11.26 |