ASP.NET MVC Pagination Not Working on ViewModel

不羁的心 提交于 2021-02-20 02:50:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!