问题
I am using pagination in my project. I have search box and sending searching text to Action Result.
I hitted break point to Search ActionResult. My news and announcements are filling after select queries.
Search ActionResult
public ActionResult Search(string searchText,int? page)
{
int pageIndex=page??1;
int dataCount=20;
dbContext=new dbContext();
SearchViewModel searchViewModel=new SearchViewModel();
var news=(from news in dbContext.News
where news.Title.Contains(searchText)
select news).ToList();
var announcement=(from announcement in dbContext.Announcement
where announcement.Title.Contains(searchText)
select announcement).ToList();
searchViewModel.News=news;
searchViewModel.Announcement=announcement;
List<SearchViewModel> searchViewModelList=new List<SearchViewModel> {searchViewModel};
return View(searchViewModelList.ToPagedList(pageIndex,dataCount));
}
SearchViewModel
public class SearchViewModel
{
public IEnumerable<News> News {get;set;}
public IEnumerable<Announcement> Annocument{get;set;}
}
My models aren't null in view. I am displaying my all data titles after searching. PagedList has showed on view but has only 1 page.
Search.cshtml
@model PagedList.IPagedList<MyProject.ViewModels.SearchViewModel>
@using PagedList
@using PagedList.Mvc
<div class=container>
@foreach (var item in Model)
{
foreach (var news in item.News)
{
@news.Title
}
foreach(var announcement in item.Announcement)
{
@announcement.Title
}
}
@Html.PagedListPager(Model,page=>Url.Action("Search",new {page=page}));
</div>
I used PagedList in my project before. But I want to use in ViewModel. Where is my wrong ?
回答1:
ToPagedList()
is designed to work with data models, not view models. What you are currently doing is returns all News
and Accouncement
records from the database by calling .ToList()
(which defeats the whole purpose of using server side paging), and the assigning all those records to the property of one instance of your view model, and then applying ToPagedList()
to that single instance.
You need to change your view model properties to IPagedList<T>
and then apply paging to each property, not the view model itself. Your view model should be
public class SearchViewModel
{
public string SearchText { get; set; }
public IPagedList<News> News { get; set; }
public IPagedList<Announcement> Annoucements { get; set; }
}
and then the controller method will be (note that your linq queries need to include an orderby clause, but I do not know which property you want to order by)
public ActionResult Search(string searchText, int? page)
{
int pageIndex = page ?? 1;
int dataCount = 20;
dbContext=new dbContext();
IQueryable<News> news = (from news in dbContext.News
where news.Title.Contains(searchText) orderby ?? select news);
IQueryable<News> announcements = (from announcement in dbContext.Announcement
where announcement.Title.Contains(searchText) orderby ?? select announcement);
SearchViewModel model = new SearchViewModel
{
SearchText = searchText,
News = news.ToPagedList(pageIndex, dataCount)
Annoucements = announcements.ToPagedList(pageIndex, dataCount)
};
return View(model);
}
Then modify the view to
@model SearchViewModel
@using PagedList
@using PagedList.Mvc
... // your form with the input for SearchText
<div class=container>
@foreach (var news in Model.News)
{
@news.Title
}
@foreach(var announcement in Model.Announcements)
{
@announcement.Title
}
@if (Model.News.Count() > Model.Announcements.Count())
{
@Html.PagedListPager(Model.News, page=>Url.Action("Search",new { page = page, searchText = Model.SearchText }));
}
else
{
@Html.PagedListPager(Model.Announcements, page=>Url.Action("Search",new { page = page, searchText = Model.SearchText }));
}
</div>
Note that the if
block ensures that the page numbers are shown in the case where you navigate to subsequent pages where you might have some News
items but no Announcement
items or vice versa. However this does not guarantee that the total number of pages will be correct (there might be say 45 matching News
records, and 65 matching Announcement
records)
来源:https://stackoverflow.com/questions/51532389/asp-net-mvc-pagination-not-working-on-viewmodel