开发者

MVC Pagination Help with query string

I'm attempting to put together a very simple application using ASP.NET MVC that shows news articles and paginates them. I'm sort of half-way there but need some help sorting out the pagination and getting it to work with the search query. This is NOT a duplication of this question (Homework) MVC Pagination Help as it deals with keeping the search query when using the pagination and was recommended to start a new question.

Here is my HomeController:

public ActionResult Index(String query, int? page)
{
        // limit the number of articles per page
        const int pageSize = 4;
        // build the query
        var ArticleQuery = from a in _db.ArticleSet select a;
        // check if their is a query
        if (!string.IsNullOrEmpty(query))
        {
            ArticleQuery = ArticleQuery.Where(a => a.headl开发者_开发技巧ine.Contains(query));
        }
        // orders the articles
        var OrderedArticles = ArticleQuery.OrderByDescending(a => a.posted);
        // takes the ordered articles and paginates them
        //var paginatedArticles = new PaginatedList(OrderedArticles.Skip((page ?? 0) * pageSize).Take(pageSize), page ?? 0, pageSize);
        var paginatedArticles = new PaginatedList<Article>(OrderedArticles, page ?? 0, pageSize);
        // return the paginated articles to the view
        return View(paginatedArticles);
}

The idea is that the Controller shows 4 items per page will order them by date. Here is the View I have for the Index method:

<ul id="pagination">
    <% if (Model.PreviousPage) { %>
        <li><%= Html.ActionLink("<< First Page", "Index")%></li>
        <li><%= Html.ActionLink("<< Previous Page", "Index", new { page=(Model.PageIndex-1) }) %></li>
    <% } %>
    <% if (Model.NextPage) { %>
        <li><%= Html.ActionLink("Next Page >>", "Index", new { page = (Model.PageIndex + 1) })%></li>
        <li><%= Html.ActionLink("Last Page >>", "Index", new { page = (Model.TotalPages - 1) })%></li>
    <% } %>    
</ul>

The idea is that these two pagination links will only show if the conditions are true.

Finally here is the PaginatedList class for the pager:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace NewsApp.Models
{
    public class PaginatedList<T> : List<T>
    {
        public int PageIndex { get; private set; }
        public int PageSize { get; private set; }
        public int TotalCount { get; private set; }
        public int TotalPages { get; private set; }

        public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize)
        {
            PageIndex = pageIndex;
            PageSize = pageSize;
            TotalCount = source.Count();
            TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);

            this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
        }
        public bool HasPreviousPage
        {
            get
            {
                return (PageIndex > 0);
            }
        }
        public bool HasNextPage
        {
            get
            {
                return (PageIndex + 1 < TotalPages);
            }
        }
    }

NOTE: I' don't want to use any 3rd party components like MVCContrib etc as this is for a University assignment so would defeat the purpose.

The pagination works fine now but when I do a search and have e.g. /?query=test I want to be able to page the results, at the moment they get lost. I'm presuming I'm going to need something such as /?query=test&page=1

Thanks.


The querystring you presented should work (try it directly in the browser to make sure).

Where you'll have an issue is when someone clicks the navigation links because the query parameter isn't accounted for in your Html.ActionLink calls. As this is homework I'll leave that as an exercise for the reader = p

Honestly, though. You should be able to figure it out from there. If not comment and I'll chime in again.

-cheers

update

So here is what you currently have your next link:

<%= Html.ActionLink("Next Page >>", "Index", new { page = (Model.PageIndex + 1) })%>

What you need to do is add query as another parameter to the ActionLink. However before you do that you need to capture the query string somewhere in your model. The dirty way of doing this is adding the query value to the ViewData and passing it that way; the clean way is adding a variable to your paginatedList class to hold the current query and setting it in the model. i.e

ViewData["query"] = query;

Or if you choose the model route:

paginatedList.Query = query;

Then you could do something like the following:

<%= Html.ActionLink("Next Page >>", "Index", new { Page = (Model.PageIndex + 1), query = ViewData["query"] /*or Model.Query */  })%>

I'm not sure how you re-setup your routing, but something similar to the above should work. You could also cache the IQueryable object, or even just the string query itself, but that's a whole other layer of abstraction.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜