I'm currently working on a reasonably simple MVC app which allows the user to enter some search data, get a list of results, then view each item etc. It's all going rather nicely, however I'm now trying to implement paging but having some trouble.
My search form uses HTTP GET, requesting the following action:
public ActionResult Results(PropertySearchData data, int? page)
{
...
IEnumerable<Property> search = mService.SearchProperties(data);
ViewData["SearchData"] = data;
return View("Results", "Site", search.ToPagedList(page ?? 0, 20));
...
}
From here I build my table of results from the IEnumerable collection passed into my view. In addition, I've used ViewData to hold the search parameters so that I can pass them on when the user requests a different page.
For example, to get to the first page, I'd like to use something like this:
Html.ActionLink("First", "Results", new { data = ViewData["SearchData"], page = 1 })
However, when this link is generated, my link is along the lines of
/Results?data=PropertySearchData&page=1
If I remove the 'page' parameter entirely, and just pass ViewData["SearchData"] as my route value, my link is generated how I'd like (ie each member of PropertySearchData is passed along as a query string through the model binding feature. I'm guessing this is because model binding can only work correctly when you've specified a single type?
I can see several reasons as to why this doesn't work; what I am having trouble with is working out the 'nice' way to do what I'm trying to do. I know that I must be lacking a vital piece of understanding here, so it would be greatly appreciated if I can get some pointers on how to approach this.
Note that I really want to stick with HTTP GET (seeing as this is a search results page).
Thanks!
The problem is the helper method is just trying it's best to generate something from what you've given it and that's an object with two properties: data and page.
To get the page number in you could make use of a route value dictionary (which is probably what's done under the hood anyway) and make use of the override that accepts an IDictionary:-
//In some HtmlHelper extension method or something
var searchCriteria = new RouteValueDictionary(ViewData["searchData"]);
searchCriteria.Add("page", 1);
return Html.ActionLink("First", "Results", searchCriteria)