Чтение DataAnnotations из коллекции моделей в представлении MCV2 - PullRequest
5 голосов
/ 18 декабря 2010

В моей MVC2 AdminArea я хотел бы создать обзорную таблицу для каждой из моих моделей домена.Я использую DataAnnotations, как показано ниже, для свойств этих объектов модели домена:

[DisplayName("MyPropertyName")]
public string Name { get; set; }

Теперь мой вопрос: как я могу получить доступ к атрибуту DisplayName, если мое представление получает коллекцию моделей моего домена?Мне нужно это для построения заголовков таблицы, которые определены вне обычного цикла

<% foreach (var item in Model) { %>

.Внутри этого цикла я могу написать

<%: Html.LabelFor(c => item.Name) %>

, но есть ли способ получить доступ к этой информации, используя коллекцию предметов вместо конкретного экземпляра?

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 18 декабря 2010

Существует класс ModelMetaData, который имеет статический метод с именем FromLambdaExpression. Если вы позвоните ему и передадите свою собственность вместе с вашим ViewData, он вернет экземпляр ModelMetaData. Этот класс имеет свойство DisplayName, которое должно дать вам то, что вам нужно. Вы также можете получить другие метаданные из этого объекта.

Например, вы можете создать пустой объект ViewDataDictionary для получения этой информации. Он может быть пустым, потому что ModelMetaData на самом деле не использует экземпляр, ему просто нужен универсальный класс для определения используемого типа.

//This would typically be just your view model data.    
ViewDataDictionary<IEnumerable<Person>> data = new ViewDataDictionary<IEnumerable<Person>>();

ModelMetadata result = ModelMetadata.FromLambdaExpression(p => p.First().Name, data);
string displayName = result.DisplayName;

Вызов метода First() не прерывается, даже если у вас нет действительного объекта Person, потому что лямбда просто пытается найти свойство, о котором вы хотите получить метаданные. Точно так же вы можете сделать это для одного Person объекта:

//This would typically be just your view model data.    
ViewDataDictionary<Person> data = new ViewDataDictionary<Person>();

ModelMetadata result = ModelMetadata.FromLambdaExpression(p => p.Name, data);

Вы можете значительно убрать это с помощью вспомогательного метода или метода расширения, но это должно поставить вас на правильный путь.

0 голосов
/ 19 декабря 2010

Хорошо, я последовал совету sgriffinusa (еще раз спасибо!) И создал строго типизированный HtmlHelper:

public static MvcHtmlString MetaDisplayName<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    return MvcHtmlString.Create(metadata.GetDisplayName());
}

Конечно, TModel по-прежнему представляет собой коллекцию моделей доменов, как указано в моем первоначальном вопросе, но мы можем вызвать помощника в представлении следующим образом:

<%: Html.MetaDisplayName(p => p.First().Name) %>
...