将@ Html.DisplayNameFor()与PagedList一起使用

nb_*_*nb_ 44 asp.net-mvc entity-framework pagedlist razor asp.net-mvc-4

我一直在尝试使用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>
Run Code Online (Sandbox Code Playgroud)

似乎IPagedList与DisplayNameFor()不兼容.知道为什么会这样,以及我如何解决它?我知道我可以手动输入列名,但我希望以后可以在模型中保留(并且可以更改)该信息.

小智 78

你可以试试这个

@Html.DisplayNameFor(model => model.FirstOrDefault().ItemName)
Run Code Online (Sandbox Code Playgroud)

  • 当序列中没有元素时,使用`First()`将抛出`InvalidOperationException`.使用`FirstOrDefault()`可以避免这种异常.或者你可以使用`FirstOrDefault`'虚拟元素',如这个重复的问题所示:http://stackoverflow.com/a/13780314/1364650 (32认同)

sal*_*iza 36

作为已接受答案的替代解决方案,请记住IPagedList继承自IEnumerable.这意味着你可以写:

@model IEnumerable<Dossier.Models.Item>
Run Code Online (Sandbox Code Playgroud)

在页面的开头,只需在需要时将模型转换为IPagedList:

@Html.PagedListPager((IPagedList)Model, page => Url.Action("Index", new { page = page }))
Run Code Online (Sandbox Code Playgroud)

您甚至可以在标题中声明已转换的变量,以便在页面中多次使用它:

@{
    ViewBag.Title = "My page title";
    var pagedlist = (IPagedList)Model;
}
Run Code Online (Sandbox Code Playgroud)

这将允许您使用DisplayNameFor帮助器方法,并访问所有PagedList方法/属性,而不需要虚拟元素,也不需要为每个字段调用.FirstOrDefault().

  • 一年后,此解决方案仍然有效。在给出的所有答案中,这个答案对我最有用,因为(a)可行,并且(b)简短而简单。 (2认同)