Simple Sorting and Pagination in ASP.NET Core with LightQuery

Georg Dangl by Georg Dangl in Web Development Tuesday, March 13, 2018

Tuesday, March 13, 2018

Posted in DotNet

With LightQuery, I've written a really small yet powerful library that assists you in paging and sorting ASP.NET Core web apps. It's a great alternative if you're looking for a simple substitution for OData or similar, heavyweight frameworks that come with great functionality but usually require a bit of setup. Additionally, LightQuery comes with clients both written in C# for .NET and also for Angular 5+ applications.

It's available both on NuGet as well as on npm.


Some time ago, I was looking to implement pagination in an ASP.NET Core Web Api call. OData wasn't yet released for .NET Core (I think it still isn't?), and all the other solutions I found required quite a bit of setup. I didn't want to deal with complex setup scenarios and neither did I want to leak library code in my controller actions, for example by specifying custom arguments or requiring setup voodoo.

All I wanted was some simple [LightQuery] attribute that I could add to any controller action and have it take care of sorting & pagination. So here's how you have to annotate a controller action in LightQuery:

Just add the [LightQuery] attribute, everything else is handled by the library and optional.

I'm using it extensively for typical, CRUD / data entry style apps, like showing thousands of users in a paged table layout. It works fine for such use cases, but it's nowhere near some feature monsters like OData.

Tip: Use [AsyncLightQuery] if you're working with Entity Framework Core for async / await support.

How Does it Work

LightQuery is purposely kept very simple. It's just a few lines and inherits from ASP.NET Cores ActionFilterAttribute.

ASP.NET Core executes the attributes OnResultExecuting() (or OnResultExecutionAsync() with Entity Framework Core) and passes the current request context. It checks for query parameters like page, pageSize or sort in the request url. If there are any, or the attribute is set to always enforce pagination, it applies the query transformation to an ObjectResult.Value property on the response. If there's no ObjectResult returned by your controller action, or its Value is not of type IQueryable, nothing happens. Go check out the source!

Controlling Pagination & Sorting on the Client Side

For clients, it's just as easy to request paged results (and thus save bandwith and time).

To paginate, send page and pageSize as url parameters in the request, like this:

There are clients both for .NET and Angular 5+ already available as prebuilt packages.

If you further want to sort by properties, you can add the sort parameter and optionally specify desc for descending sort order, otherwise it defaults to ascending. If you specify a non-existent property, there'll be no sorting. The following request returns the users, sorted by descending email property: desc

Tip: Title casing is taken care of, so email works both for Email and email properties.

Do you want to know more? Head over to the GitHub repository to find more examples.

Happy Paging!

Share this post

comments powered by Disqus

About me

Hi, my name's George! I love coding and blogging about it. I focus on all things around .Net, Web Development and DevOps.


Need a consultant for BIM, GAEB or Software Development?

Contact me at [email protected], +49 (173) 56 45 689 or visit my professional page!

// Just 💗 Coding

Social Links