Подтвердить что ты не робот

Вызов IEnumerable перегрузки DisplayNameFor

Это работает для захвата заголовков (NOT VALUES):

@model IEnumerable<SomeModel>
...
<th>@Html.DisplayNameFor(m => m.SomeModelProperty)</th>

Что, если SomeModelProperty:

[Display(Name = "An Excellent Header")]
SomeModelProperty { get; set; }

Затем он отобразит "Отличный заголовок" в элементе заголовка th.

Вы бы подумали, что это не сработает, потому что модель IEnumerable, у которой не будет m.SomeModelProperty, но она работает, потому что у HtmlHelper есть HtmlHelper<IEnumerable<TModel>>, так что параметр лямбда TModel, а не IEnumerable<TModel>. Поскольку это просто использует метаданные, нет необходимости в элементе из коллекции. (Хотя intellisense на m. будет лгать вам и заставляет вас думать, что это коллекция). Я не уверен, когда эта прохладная перегрузка была добавлена, но довольно удобна для Index.cshtml и устраняет напуганные вещи, такие как @Html.DisplayNameFor(m => @Model.FirstOrDefault().SomeModelProperty), которые я хочу избежать.

http://msdn.microsoft.com/en-us/library/hh833697(v=vs.108).aspx

Однако я не могу понять, как заставить это работать, когда моя модель не IEnumerable, но вместо этого содержит IEnumerable как свойство, например:

public class SomeList
{
   public List<SomeModel> SomeModels { get; set; }
   public int Page { get; set; }
   public DateTime CurrentAsOf { get; set; }
}

Я надеялся быть явным с параметрами типового типа, но я думаю, что параметры типа задаются движком, который просачивается из HtmlHelper, созданного на странице. Можно ли объявить новый HtmlHelper на странице или каким-либо образом указать параметры типа явно?

Index.cshtml:

@model SomeList
//No idea how to do this:
@Html.DisplayNameFor<IEnumerable<SomeModel>>(m => m.SomeModelProperty)
4b9b3361

Ответ 1

Другое подобное обходное решение, которое работает, даже если нет строк, может быть:

...
@{var dummy = Model.FirstOrDefault(); }
    <tr>
        <th>
            @Html.DisplayNameFor(model => dummy.SomeModelProperty)
        </th>
...

Ответ 2

У меня точно такая же проблема, потому что я использую ViewModels, поэтому у меня есть ViewModel с IEnumerable фактических объектов как свойство.

Я столкнулся с этим сообщением, где, если вы проверите ответ, парень создал свой собственный HTMLHelper для решения этой проблемы http://forums.asp.net/t/1783733.aspx, Его версия:

public static MvcHtmlString DisplayColumnNameFor<TModel, TClass, TProperty>(
    this HtmlHelper<TModel> helper, IEnumerable<TClass> model, 
    Expression<Func<TClass, TProperty>> expression)
{
    var name = ExpressionHelper.GetExpressionText(expression);
    name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(
        () => Activator.CreateInstance<TClass>(), typeof(TClass), name);

    return new MvcHtmlString(metadata.DisplayName);
}

Вам нужно передать два аргумента перечисления и выражения, а не нормальное простое выражение, чтобы вы могли предпочесть ответ @franz. Я не вижу, что в любом случае вам придется пройти 2 аргумента, так как он должен знать, какое свойство модели представления вы применяете для выражения.