Utiliser @ Html.DisplayNameFor () avec PagedList

J’ai essayé le package PagedList pour obtenir la pagination de mes vues d’index. Tout se passait bien et au niveau du contrôleur, tout fonctionnait bien, il affichait seulement 5 enregistrements par page et affichait la page appropriée en fonction de la chaîne de requête.

Mon problème est dans la vue. J’ai changé @Model en PagedList.IPagedList pour pouvoir accéder à Model.HasNextPage et à d’autres propriétés, mais maintenant le @Html.DisplayNameFor(model => model.ItemName) ne fonctionne plus. Je reçois cette erreur:

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

Voici les parties pertinentes de la vue:

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

Il semble qu’IPagedList n’est pas compatible avec DisplayNameFor (). Toute idée de ce qui se passe et comment je pourrais le réparer? Je sais que je pourrais simplement entrer manuellement les noms des colonnes, mais j’aimerais que cette information rest (et soit modifiable) plus tard dans le modèle.

Vous pouvez essayer ceci

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

En tant que solution alternative à la réponse acceptée, rappelez-vous que IPagedList hérite de IEnumerable. Cela signifie que vous pourriez écrire:

 @model IEnumerable 

Au début de la page, il suffit de convertir le modèle en IPagedList si nécessaire:

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

Vous pouvez même déclarer la variable convertie dans l’en-tête, afin de l’utiliser plusieurs fois dans la page:

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

Cela vous permet d’utiliser la méthode d’assistance DisplayNameFor et d’accéder à toutes les méthodes / propriétés PagedList, sans avoir besoin d’éléments factices ni d’appeler .FirstOrDefault () pour chaque champ.

J’ai résolu le problème en créant une surcharge de DisplayNameFor qui accepte un IPagedList .

 namespace PagedList.Mvc { public static class Extensions { [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] public static MvcHtmlSsortingng DisplayNameFor(this HtmlHelper> html, Expression> expression) { return DisplayNameForInternal(html, expression); } [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This is an extension method")] internal static MvcHtmlSsortingng DisplayNameForInternal(this HtmlHelper> html, Expression> expression) { return DisplayNameHelper(ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary()), ExpressionHelper.GetExpressionText(expression)); } internal static MvcHtmlSsortingng DisplayNameHelper(ModelMetadata metadata, ssortingng htmlFieldName) { ssortingng resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); return new MvcHtmlSsortingng(HttpUtility.HtmlEncode(resolvedDisplayName)); } } } 

Je vais envoyer une demande d’extraction au projet PageList pour l’inclure dans le projet pour tout le monde.

Vous n’avez pas besoin de changer @Html.DisplayNameFor . Déclarer le modèle dans la vue en tant que:

 @model IEnumerable 

Déplacez simplement votre pager sur une vue partielle (appelez-le “_Pager”):

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

Rendez le pager dans votre vue:

 @Html.Partial("_Pager", Model) 

C’est tout.

PS Vous pouvez créer une aide HTML au lieu d’une vue partielle …