paginacion net mvc framework example bootstrap asp application asp.net-mvc entity-framework razor asp.net-mvc-4 pagedlist

asp.net mvc - net - Usando @ Html.DisplayNameFor() con PagedList



paginacion mvc 5 c# (4)

He estado probando el paquete PagedList para obtener una paginación para mis vistas de índice. Todo iba bien, y en el nivel del controlador todo funciona bien, solo muestra 5 registros por página y muestra la página adecuada en función de la cadena de consulta.

Mi problema está en la vista. Cambié @Model a PagedList.IPagedList para poder acceder a Model.HasNextPage y a otras propiedades, pero ahora el @Html.DisplayNameFor(model => model.ItemName) ya no funciona. Me sale este error:

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?)

Aquí están las partes relevantes de la vista:

@model PagedList.IPagedList<Dossier.Models.Item> @using Dossier.Models.Item ... <th> @Html.DisplayNameFor(model => model.ItemName) </th>

Parece que IPagedList no es compatible con DisplayNameFor (). ¿Alguna idea de por qué está sucediendo esto y cómo podría solucionarlo? Sé que podría ingresar manualmente los nombres de las columnas, pero me gustaría que esa información permanezca (y se pueda modificar) en el modelo más adelante.


Como solución alternativa a la respuesta aceptada, recuerde que IPagedList hereda de IEnumerable. Eso significa que podrías escribir:

@model IEnumerable<Dossier.Models.Item>

Al comienzo de la página, y simplemente transfiera el modelo a IPagedList cuando sea necesario:

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

Incluso puede declarar la variable emitida en el encabezado, para usarla varias veces en la página:

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

Esto le permitiría usar el método DisplayNameFor helper y acceder a todos los métodos / propiedades de PagedList, sin la necesidad de elementos ficticios ni llamar a .FirstOrDefault () para cada campo.


No necesita cambiar @Html.DisplayNameFor . Declarar el modelo en la vista como:

@model IEnumerable<Dossier.Models.Item>

Simplemente mueva su buscapersonas a una vista parcial (asígnele el nombre "_Pager"):

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

Renderiza el buscapersonas en tu vista:

@Html.Partial("_Pager", Model)

Eso es.

PD: puede crear Html helper en lugar de vista parcial ...


Puedes intentar esto

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


Resolví el problema creando una sobrecarga de DisplayNameFor que acepta una 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)); } } }

Enviaré una solicitud de extracción al proyecto PageList para incluirla en el proyecto para todos.