我不知所措,因为我必须遗漏一些东西。刚刚完成ASP.NET MVC 1.0(WROX),我试图实现一个执行简单搜索的视图,然后在表中呈现结果。然后,我希望能够通过结果进行分页。
所以我有一个来自ListingsController的搜索操作,从FormCollection获取一些值并相应地过滤结果:
//
//POST: /Listings/Search
// /Listings/Page/2
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(FormCollection collection,int? page)
{
var listings = listingRepository.GetListings();
//filter
if (collection["TypeOfHouse"] != null)
{
string[] typeList = collection["TypeOfHouse"].Split(',');
foreach (string type in typeList)
{
listings = from l in listings
where l.TypeOfHouse == type
select l;
}
}
//display the first page of results
int pageSize = 25;
var paginatedListings = new PriviledgeV1.Helpers.PaginatedList<Listing>(listings, 0, pageSize);
return View("Results", paginatedListings);
}
最初,结果视图将使用第1页的前25条记录进行渲染。然后我有一个处理“分页”的结果操作:
public ActionResult Results(int? page)
{
int pageSize = 25;
var listings = listingRepository.GetListings();
var paginatedListings = new PriviledgeV1.Helpers.PaginatedList<Listing>(listings, page ?? 0, pageSize);
return View(listings);
}
麻烦是因为我不再拥有FormCollection,我无法正确过滤结果。因此,如果我尝试使用/ Listings / Results?page = 2从第1页移至第2页,则结果操作将触发,它将返回所有结果,而不是搜索操作中的过滤结果集。
我真的很困惑这里要做什么,以及为什么没有博客/教程解释这一点,这通常标志着我错过了一些东西。
谢谢!
答案 0 :(得分:5)
我想有几种方法可以尝试实现这一目标。
Results
操作。我确信我们可以从那里获得更多创意,但这应该会给你一个开始。您似乎只关心搜索表单中的一个字段TypeOfListing
。你应该可以很容易地通过查询字符串来保存它,所以这就是上面的方法#1。
<强>更新强>
这是我为了在客户端维护您的搜索而放在一起的简单内容。该技术涉及三个部分:
这是所有各种部分的代码。请注意,我使用jQuery,以防您喜欢其他内容。我捏造了数据源,只是在实际数据中。此外,我还包括PagedList和PaginationHelper。如果你愿意,可以用你自己代替。
\ Controllers \ HomeController.cs (搜索是相关部分):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication2.Controllers
{
[HandleError]
public class HomeController : Controller
{
List<String> _data;
public HomeController()
{
_data = new List<String>();
_data.Add("Merry");
_data.Add("Metal");
_data.Add("Median");
_data.Add("Medium");
_data.Add("Malfunction");
_data.Add("Mean");
_data.Add("Measure");
_data.Add("Melt");
_data.Add("Merit");
_data.Add("Metaphysical");
_data.Add("Mental");
_data.Add("Menial");
_data.Add("Mend");
_data.Add("Find");
}
public ActionResult Search()
{
Int32 pageNumber, pageSize = 5, total, first;
String typeOfListing;
PagedList<String> results;
if (Request.HttpMethod == "GET")
{
return View();
}
if (!Int32.TryParse(Request.Form["PageNumber"], out pageNumber)) pageNumber = 1;
typeOfListing = Request.Form["TypeOfListing"];
first = (pageNumber - 1) * pageSize;
total = (from s in _data
where s.Contains(typeOfListing)
select s).Count();
results = new PagedList<String>(
(from s in _data
where s.Contains(typeOfListing)
select s)
.Skip(first)
.Take(pageSize),
total, pageNumber, pageSize);
return View(results);
}
}
}
<强> \助手\ PaginationHelper.cs 强>:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Web.Routing;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace MvcApplication2.Helpers
{
public static class PaginationHelper
{
public static String Pager(this HtmlHelper helper, Int32 pageSize, Int32 pageNumber, Int32 total, String actionName, RouteValueDictionary values)
{
StringBuilder output = new StringBuilder();
Int32 totalPages = (Int32)Math.Ceiling((Double)total / pageSize);
if (values == null)
values = helper.ViewContext.RouteData.Values;
if (pageNumber > 1)
output.Append(CreatePageLink(helper, values, "< Previous ", pageNumber - 1, pageSize));
for (Int32 i = 1; i <= totalPages; i++)
{
if (i == pageNumber)
output.Append(i);
else
output.AppendFormat(CreatePageLink(helper, values, i.ToString(), i, pageSize));
if (i < totalPages)
output.Append(" | ");
}
if (pageNumber < totalPages)
output.Append(CreatePageLink(helper, values, " Next >", pageNumber + 1, pageSize));
return output.ToString();
}
private static String CreatePageLink(HtmlHelper helper, RouteValueDictionary values, String text, Int32 pageNumber, Int32 pageSize)
{
RouteValueDictionary routeDictionary = new RouteValueDictionary(values);
routeDictionary.Add("page", pageNumber);
routeDictionary.Add("pageSize", pageSize);
return helper.ActionLink(text, null, routeDictionary);
}
}
}
<强> \ PagedList.cs 强>:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication2
{
public class PagedList<T> : List<T>
{
public Int32 TotalCount { get; protected set; }
public Int32 PageNumber { get; protected set; }
public Int32 PageSize { get; protected set; }
public PagedList(IEnumerable<T> items, Int32 total, Int32 pageNumber, Int32 pageSize)
: base(items)
{
TotalCount = total;
PageNumber = pageNumber;
PageSize = pageSize;
}
}
}
<强> \视图\主页\ Search.aspx 强>:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<PagedList<String>>" %>
<%@ Import Namespace="MvcApplication2" %>
<%@ Import Namespace="MvcApplication2.Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Search
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(function() {
var results = $("#searchResults");
if (results && results.children().length > 2) {
$("#searchForm").hide();
$("#searchResults .pager>a").click(submitForm);
}
});
function submitForm() {
var m = this.href.match(/page=(\d+)/i);
if (m) {
$("#PageNumber").attr("value", m[1]);
$("#searchForm").submit();
}
return false;
}
</script>
<form id="searchForm" action="<%= Url.Action("Search") %>" method="post">
<input type="hidden" value="1" id="PageNumber" name="PageNumber" />
<fieldset>
<legend>Search</legend>
<label for="TypeOfListing">Type of Listing</label>
<%= Html.TextBox("TypeOfListing", Request.Form["TypeOfListing"]) %>
<input type="submit" id="btnSubmit" name="btnSubmit" value="Search" />
</fieldset>
</form>
<% if (Model != null)
{
%>
<div id="searchResults">
<div class="results-count">Displaying <%=this.Model.Count %> of <%=this.Model.TotalCount %> results. <%=Html.ActionLink("Start a new search", "Search") %>.</div>
<%
foreach (String result in Model)
{
%>
<div class="result"><%=result %></div>
<% }
%>
<div class="pager"><%= Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalCount, null, null) %></div>
</div>
<%
}
%>
</asp:Content>
答案 1 :(得分:0)
基本上按照其他人的建议更改您的表单以执行HTTP GET,然后使用Nuget下载PagedList,并在您的操作方法中使用模型绑定到来自PagedList的HTML帮助函数的提交按钮和页码(并设置路径)使用RouteValuesDictionary的值)。这样一切都会在查询字符串中持久化,这也是您最想要的搜索页面。 MVC将与您的ViewModel类进行协调。我更喜欢使用ViewModel类而不是一堆参数,因为我觉得它更干净,但只是我的$ .02。
我有一个关于here的博客的例子。