Получение значения атрибута DisplayName в контроллере ASP.NET MVC

26.12.2010 21:41 / Артём Волк / 886 просмотров / ...

Дополнение от 29.03.2011: Код обновлён для поддержки метаданных, определённых с помощью partial-классов и атрибута [MetadataType]

В случае, если для снабжения модели ASP.NET MVC приложения метаданными используются DataAnnotations, например так:

public class MyViewModel
{	
	[DisplayName("Имя пользователя")]
	public string UserName { get; set; }

	...
}

Для программного получения значения атрибута [DisplayName], например, в коде контроллера, можно воспользоваться следующим методом (оригинал решения):

public static class MetaDataHelper
{
	public static string GetDisplayName(Type dataType, string fieldName)
	{		
		// First look into attributes on a type and it's parents
		DisplayNameAttribute attr;
		attr = (DisplayNameAttribute)dataType.GetProperty(fieldName).GetCustomAttributes(typeof(DisplayNameAttribute), true).SingleOrDefault();

		// Look for [MetadataType] attribute in type hierarchy
		// http://stackoverflow.com/questions/1910532/attribute-isdefined-doesnt-see-attributes-applied-with-metadatatype-class
		if (attr == null)
		{
			MetadataTypeAttribute metadataType = (MetadataTypeAttribute)dataType.GetCustomAttributes(typeof(MetadataTypeAttribute), true).FirstOrDefault();
			if (metadataType != null)
			{
				var property = metadataType.MetadataClassType.GetProperty(fieldName);
				if (property != null)
				{
					attr = (DisplayNameAttribute)property.GetCustomAttributes(typeof(DisplayNameAttribute), true).SingleOrDefault();
				}
			}
		}
		return (attr != null) ? attr.DisplayName : String.Empty;
	}
}

Пример использования:

string fieldDisplayName = MetaDataHelper.GetDisplayName(typeof(MyViewModel), "UserName");

Минус решения — имя поля приходится указывать в виде строки, возможно и строго типизированное решение.