I’ve been working on a project using MVC (my first real go around) with Entity Framework providing my model. I’ve been learning a ton of little tricks and I figured I’d better start capturing them now before I lose them or forget. Then 6 months from now I’ll be going, “now where did I have that code that…” LOL
So, to facilitate my own learning curve, I build a very simply database to track my music of interest. I have a table for songs, albums and artists. When displaying Artists, I found that I wanted pagination on the page. I started looking around on the web and found there are tons of different ways of doing it, many that did not make sense to me and none that I tried that actually worked. Therefore, I began working it myself. Here’s how I did it. In the ArtistController (I’ll be doing other posts to explain MVC – if this doesn’t make sense now my apologies. I am handling this topic in a little bit of a scattered way) I added the following Action:
public ActionResult Paged(int page, int pagesize = 5)
ViewBag.Page = page;
ViewBag.PageSize = pagesize;
int skip = (page - 1) * pagesize;
var artists = db.Artists
.OrderBy(c => c.ArtistName)
You can see that this Action takes two parameters, both int. One that represents what page you are on (page) and how many entries are on a page (pagesize). So a 5 and 10 means go to the fifth page where there are ten artists on each page. I pass these values to the ViewBag so I can reference them in the View. I then calculate how far to skip ahead in the model (skip = (page-1)*pagesize). I then use the LINQ statement that says use the Artist model (db represents my EF model with Artists being a class within that model), ordering by artist’s name but that skips the first ‘skip’ artists and takes the next ‘pagesize’ after that. When this LINQ query executes, it will get the artists that I am looking for based on the pagination data provided. Simple right?
Then, in the view that this Action brings up, I used basically the same View that I did for the default Index View and Controller, but I demonstrate how the ViewBag facilitates the exchange of information (i.e. what page the user is on and how many are on a page):
On page @ViewBag.Page with a page size of @ViewBag.PageSize.
My MVC is using the RAZOR engine, making the use of the ViewBag so simple. All that is left (which I haven’t done yet, but will update with when complete) is to build a nice looking control to facilitate the visualization of the paging and including links to flip back and forth on pages like you see in most web apps. The URL to call say the 3rd page of Artists when we are viewing 10 Artists per page looks like: http://localhost:5027/Artist/Paged/x?page=3&pagesize=10 Artist is the name of my controller. Paged in the Action defined above. And the rest is simply putting the data into the query string. Easy right? :-)
More to come, but I wanted to document this while I am on it. I’ll be hitting some of the basics and some of the little nuances that I pick up along the way. I’ve found that the tutorials out there (especially those provided by Microsoft) do an excellent job of showing the basics and the norms. But when do our projects stick to the simple and norms? ;-) So I will document some of those other cases in my blog. Hope this helps!
First, one think for me that made the other posts online difficult to follow was the ordering of items. In order to do paging, you have to touch the controller and the view at different points. In cases like these, a picture is worth a thousand words to me. So, to be helpful, here is a picture of the interconnections:
Controller and View – click to see larger and clearer
The controller is our starting point for this discussion. The user has come to the controller by entering the appropriate url or through navigations you have provided. The key is the method that it comes to returns an ActionResult. This points the user to the View intended. So we are now off to the View. Inside the view, you may need to facilitate some interaction with the user. For this example, I wanted the user to be able to pick how many log entries were being displayed on the page at a time (hence paging). Now, this selection doesn’t have anything to do with the data model (I am using Entity Framework for this application – if you haven’t used EF, check it out! It is really a great piece of technology. Extremely robust and fun to use! Powerful while being a logical abstraction.) so I really don’t want to cross concerns and implement a page size concept in my model.
What’s needed is a simple HTML form. Notice in the diagram, I have some of the HTML of the View shown. There is a HTML form that contains:
Html.BeginForm("ChosePageSize", "CentralLog", FormMethod.Get)
This forms contains a drop down list that enables the user to select pre-fixed page sizes. The first parameter is a string of ChosePageSize. This is the critical part to understand. That string is the name of the method back in the controller that will be called when this form is submitted. The data collected in this form is then available to the controller. Let’s look at the ChosePageSize method in a little detail.