Enhancing the WebGrid: Paging

February 10th, 2016

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

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);
}

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.