Enhancing the WebGrid: Paging

Here we go adding another WebGrid enhancement. Today, we focus on the simplest function in a WebGrid: Paging.

Written by Jonathan "JD" Danylko • Last Updated: • MVC •
Persons hand thumbing through a book.

I got so carried away with the other features in the WebGrid, I forgot about the most simplest of function of all: Paging.

The WebGrid has paging built into it, but there are tricks in optimizing each function.

Today, I will go over the easiest way to implement paging for your WebGrid and then follow up on Friday with a way to create an awesome pager that gives your users more control.

We Danced This Dance Before

A while ago, I mentioned how to attach query parameters to a model using model binders. This post was grabbing the query string parameters and making a model through the model binder.

However, before we continue, we need to create the proper models first.

The PagingModel is exactly the same as before only we added the two parameters.

ViewModel\PagingModel.cs

[ModelBinder(typeof(PagingBinder))]
public class PagingModel
{
    public int PageIndex { getset; }
    public int PageSize { getset; }
}

Now we look at the ModelBinder.

ModelBinder\PagingBinder.cs

public class PagingBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var pageNum = request.QueryString.Get("Page");
        var size = request.QueryString.Get("Size");
        int pageNumber;
        if (!int.TryParse(pageNum, out pageNumber))
            pageNumber = 1; // Default Page
        var pageIndex = pageNumber - 1;
        int pageSize;
        if (!int.TryParse(size, out pageSize))
            pageSize = 10; // Default 10 records
        return new PagingModel
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            PageNumber = pageNumber
        };
    }
}

This is all we need to do to accept paging parameters in the Url. We make the ModelBinder do the hard work.

So as the WebGrid passes Query Strings through the Url, all we do is collect the parameters.

Now that we have our paging model and PagingBinder defined, we can pass it seamlessly through to our controller.

Our UserController now has a single parameter on the HttpGet.

// GET: User
public ActionResult Index(PagingModel paging)
{
    var model = new UserViewModel
    {
        Users = _repository.GetAll()
    };
    return View(model);
}

When we access the page initially, our PageNumber is set to one, the PageSize is set to 10, and we automatically calculate the PageIndex.

Modifying our Repository

One of the easiest way to return paged records using Entity Framework is to use the Skip and Take methods.

These two methods are essential for implementing a paging strategy.

The Skip method takes our page index and initially says skip 0 records (0 * 10 = 0) and then Take 10 records.

All we need to do is create an additional method called GetPagedUsers and let Entity Framework do all of the calculating of records for our grid.

public IEnumerable<User> GetPagedUsers(PagingModel model)
{
    return GetAll()
        .OrderBy(e => e.UserName)
        .Skip(model.PageIndex*model.PageSize)
        .Take(model.PageSize)
        .ToList();
}

For populating our model, we replace our GetAll() method with the GetPagedUsers() and Voila! We get 10 users in our grid.

// GET: User
public ActionResult Index(PagingModel paging)
{
    var model = new UserViewModel
    {
        Users = _repository.GetPagedUsers(paging)
    };
    return View(model);
}

WebGrid containing only 10 records

Conclusion

Today, we focused on how to include paging into the WebGrid. We can easily replace our UserRepository with a StoredProcedure that returns back only a small set of records to the client.

On Friday, I will show you how to spice up your paging to empower your users with even more functionality.

Post your comments below about this technique.

Did you like this content? Show your support by buying me a coffee.

Buy me a coffee  Buy me a coffee
Picture of Jonathan "JD" Danylko

Jonathan Danylko is a web architect and entrepreneur who's been programming for over 25 years. He's developed websites for small, medium, and Fortune 500 companies since 1996.

He currently works at Insight Enterprises as an Principal Software Engineer Architect.

When asked what he likes to do in his spare time, he replies, "I like to write and I like to code. I also like to write about code."

comments powered by Disqus