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

Использование @Html.DisplayNameFor() с PagedList

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

Моя проблема в представлении. Я изменил @Model на PagedList.IPagedList, чтобы получить доступ к Model.HasNextPage и другим свойствам, но теперь @Html.DisplayNameFor(model => model.ItemName) больше не работают. Я получаю эту ошибку:

PagedList.IPagedList<Dossier.Models.Item>' does not contain a definition for 'ItemName' and no extension method 'ItemName' accepting a first argument of type 'PagedList.IPagedList<Dossier.Models.Item>' could be found (are you missing a using directive or an assembly reference?)

Вот соответствующие части представления:

@model PagedList.IPagedList<Dossier.Models.Item>
@using Dossier.Models.Item

...

<th>
    @Html.DisplayNameFor(model => model.ItemName)
</th>

Кажется, IPagedList несовместим с DisplayNameFor(). Любая идея, почему это происходит, и как я могу это исправить? Я знаю, что могу просто вручную ввести имена столбцов, но мне хотелось бы, чтобы эта информация оставалась (и была изменчивой) в модели позже.

4b9b3361

Ответ 1

Вы можете попробовать это

@Html.DisplayNameFor(model => model.FirstOrDefault().ItemName)

Ответ 2

В качестве альтернативного решения принятого ответа помните, что IPagedList наследует от IEnumerable. Это означает, что вы можете написать:

@model IEnumerable<Dossier.Models.Item>

В начале страницы и просто приведите модель к IPagedList при необходимости:

@Html.PagedListPager((IPagedList)Model, page => Url.Action("Index", new { page = page }))

Вы даже можете объявить переменную casted в заголовке, чтобы использовать ее несколько раз на странице:

@{
    ViewBag.Title = "My page title";
    var pagedlist = (IPagedList)Model;
}

Это позволит вам использовать метод DisplayNameFor helper и получить доступ ко всем методам/свойствам PagedList, без необходимости использования фиктивных элементов или вызова .FirstOrDefault() для каждого поля.

Ответ 3

Я решил проблему, создав перегрузку DisplayNameFor, которая принимает IPagedList<TModel>.

namespace PagedList.Mvc
{
    public static class Extensions
    {

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
        public static MvcHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<IPagedList<TModel>> html, Expression<Func<TModel, TValue>> expression)
        {
            return DisplayNameForInternal(html, expression);
        }

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This is an extension method")]
        internal static MvcHtmlString DisplayNameForInternal<TModel, TValue>(this HtmlHelper<IPagedList<TModel>> html, Expression<Func<TModel, TValue>> expression)
        {
            return DisplayNameHelper(ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary<TModel>()),
                                     ExpressionHelper.GetExpressionText(expression));
        }

        internal static MvcHtmlString DisplayNameHelper(ModelMetadata metadata, string htmlFieldName)
        {
            string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

            return new MvcHtmlString(HttpUtility.HtmlEncode(resolvedDisplayName));
        }
    }
}

Я отправлю запрос на перенос в проект PageList, чтобы включить его в проект для всех.

Ответ 4

Вам не нужно менять @Html.DisplayNameFor. Объявите модель в представлении как:

@model IEnumerable<Dossier.Models.Item>

Просто переместите пейджер на частичный просмотр (давайте назовите его "_Pager" ):

@model IPagedList

...

@Html.PagedListPager(Model, 
   page => Url.Action("Index", new { page, pageSize = Model.PageSize }))

...

Отметьте пейджер в своем представлении:

@Html.Partial("_Pager", Model)

Вот оно.

P.S. Вы можете создать Html-помощник вместо частичного представления...