PagedList loses search filter on second page

Robbie Mills picture Robbie Mills · Sep 10, 2013 · Viewed 18.8k times · Source

I'm implementing a simple paged list Index using the example at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application

My problem is that the search string is 'lost' when I page to the second page, so instead of a filtered set of results, I'm shown all the records.

My index.cshtml:

@using (Html.BeginForm("Index", "", FormMethod.Get))
{
    <p>
        @Html.TextBox("searchString", ViewBag.currentFilter as string, new { @placeholder = "Search by title or author" })
        <input type="submit" value="Search" />
    </p>
}

@if (Model.PageCount > 1)
{ 
    @Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )
}

My controller:

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
    {
        ViewBag.TitleSortParm = sortOrder == "Title" ? "Title desc" : "Title";
        ViewBag.AuthorSortParm = sortOrder == "Author" ? "Author desc" : "Author";
        ViewBag.DateSortParm = sortOrder == "Date" ? "Date desc" : "Date";

        if (searchString != null)
        {
            page = 1;
        }
        else
        {
            searchString = currentFilter;

        }

        ViewBag.currentFilter = searchString;

        var Articles = from a in db.Articles
                       select a;
        if (!String.IsNullOrEmpty(searchString))
        {
            //page = 1;
            Insights = Articles.Where(s => s.Title.ToUpper().Contains(searchString.ToUpper())
                               || s.Author.ToUpper().Contains(searchString.ToUpper()));
        }

        switch (sortOrder)
        {
            case "Author":
                Insights = Articles.OrderBy(s => s.Author);
                break;
            case "Author desc":
                Insights = Articles.OrderByDescending(s => s.Author);
                break;
            case "Title":
                Insights = Articles.OrderBy(s => s.Title);
                break;
            case "Title desc":
                Insights = Articles.OrderByDescending(s => s.Title);
                break;
            case "Date":
                Insights = Articles.OrderBy(s => s.DatePublished);
                break;
            default:
                Insights = Articles.OrderByDescending(s => s.DatePublished);
                break;
        }
        int pageSize = 3;
        int pageNumber = (page ?? 1);
        return View(Articles.ToPagedList(pageNumber, pageSize));

    }

When I go to Page 2 as an example, all my variables, sortOrder, currentFilter and searchString are all null.

Robbie

Answer

Evonet picture Evonet · Sep 11, 2013

The problem is your PagedList entry doesn't include your sort order nor your current filter.

In addition to adding ViewBag.CurrentSort as suggested by Vasanth, you also need to change your PagedListPager to:

@Html.PagedListPager( Model, page => Url.Action("Index", new { page, currentFilter=ViewBag.CurrentFilter, sortOrder = ViewBag.sortOrder}) )