ASP.NET MVC 分页不适用于 ViewModel [英] ASP.NET MVC Pagination Not Working on ViewModel
问题描述
我在我的项目中使用分页.我有搜索框并将搜索文本发送到操作结果.
我遇到了 Search ActionResult 的断点.选择查询后,我的新闻和公告正在填写.
搜索操作结果
public ActionResult Search(string searchText,int? page){int pageIndex=page??1;int dataCount=20;dbContext=new dbContext();SearchViewModel searchViewModel=new SearchViewModel();var 新闻=(来自 dbContext.News 中的新闻其中 news.Title.Contains(searchText)选择新闻.ToList();var 公告=(来自 dbContext.Announcement 中的公告其中announcement.Title.Contains(searchText)选择公告).ToList();searchViewModel.News=news;searchViewModel.Announcement=公告;列表searchViewModelList=新列表{搜索视图模型};返回视图(searchViewModelList.ToPagedList(pageIndex,dataCount));}
SearchViewModel
公共类 SearchViewModel{公共 IEnumerable<新闻>新闻{get;set;}公共 IEnumerable<公告>公告{get;set;}}
我的模型不是空的.我在搜索后显示我的所有数据标题.PagedList 已显示在视图中,但只有 1 页.
Search.cshtml
@model PagedList.IPagedList@using PagedList@using PagedList.Mvc<div 类=容器>@foreach(模型中的变量项目){foreach(item.News 中的 var 新闻){@news.Title}foreach(在 item.Announcement 中的 var 公告){@announcement.Title}}@Html.PagedListPager(Model,page=>Url.Action("Search",new {page=page}));
我之前在我的项目中使用过 PagedList.但我想在 ViewModel 中使用.我哪里错了?
ToPagedList()
旨在处理数据模型,而不是视图模型.您当前所做的是通过调用 .ToList()
从数据库返回所有 News
和 Accouncement
记录(这违背了使用的全部目的)服务器端分页),并将所有这些记录分配给视图模型的一个实例的属性,然后将 ToPagedList()
应用于该单个实例.
您需要将视图模型属性更改为 IPagedList
,然后将分页应用于每个属性,而不是视图模型本身.你的视图模型应该是
公共类 SearchViewModel{公共字符串 SearchText { 获取;放;}public IPagedList<新闻>新闻{得到;放;}public IPagedList<公告>公告{得到;放;}}
然后控制器方法将是(注意您的 linq 查询需要包含一个 orderby 子句,但我不知道您要根据哪个属性进行排序)
public ActionResult Search(string searchText, int? page){int pageIndex = 页 ??1;int dataCount = 20;dbContext=new dbContext();IQueryable<新闻>新闻 =(来自 dbContext.News 中的新闻其中 news.Title.Contains(searchText) orderby ??选择新闻);IQueryable<新闻>公告 =(来自 dbContext.Announcement 中的公告其中announcement.Title.Contains(searchText) orderby ??选择公告);SearchViewModel 模型 = 新的 SearchViewModel{搜索文本 = 搜索文本,新闻 = news.ToPagedList(pageIndex, dataCount)公告 = 公告.ToPagedList(pageIndex, dataCount)};返回视图(模型);}
然后将视图修改为
@model SearchViewModel@using PagedList@using PagedList.Mvc...//带有 SearchText 输入的表单<div 类=容器>@foreach(Model.News 中的 var 新闻){@news.Title}@foreach(Model.Announcements 中的 var 公告){@announcement.Title}@if (Model.News.Count() > Model.Announcements.Count()){@Html.PagedListPager(Model.News, page=>Url.Action("Search",new { page = page, searchText = Model.SearchText }));}别的{@Html.PagedListPager(Model.Announcements, page=>Url.Action("Search",new { page = page, searchText = Model.SearchText }));}
请注意,if
块可确保在您导航到可能有一些 News
项目但没有 的后续页面的情况下显示页码公告
项,反之亦然.然而,这并不能保证总页数是正确的(可能有 45 条匹配的 News
记录和 65 条匹配的 Announcement
记录)
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 ?
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)
这篇关于ASP.NET MVC 分页不适用于 ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!