To add sorting and pagination to an ASP.NET MVC table, keep the view state—sort order, filter, and page—in the request, apply filtering and ordering to the query in the controller, and return only the requested page when paging on the server. Razor renders the links and rows; optional jQuery code handles interactions in the browser. Classic ASP.NET MVC and ASP.NET Core MVC use different APIs, so choose the implementation pattern for your project.
How sorting and pagination fit together
A table view spans three layers. The controller accepts the requested sort, filter, and page; the query applies those choices; and the Razor view renders the results and navigation links. When using a browser-side table plugin, jQuery works with the HTML and data delivered to the browser. Razor itself does not sort an already-rendered table in the browser.
For controller-and-view sorting and paging in classic ASP.NET MVC, see Microsoft’s ASP.NET MVC tutorial. For an ASP.NET Core MVC application using EF Core, use the distinct Microsoft tutorial for sorting, filtering, and paging.
Build sorting and paging in classic ASP.NET MVC
The classic MVC tutorial demonstrates a controller action that orders a query according to a supported sort value, then supplies the view with the data and state it needs. Its paging example uses a paged-list object and a pager helper; that helper is part of the tutorial’s chosen implementation, not a built-in Razor pagination feature.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches#1 Best Overall
1. Accept the table state in the action
Use explicit action parameters for the sort value, filter text, and requested page. Treat sort values as a finite set of supported choices: select the relevant ordering in a switch or equivalent mapping rather than treating arbitrary request text as a field or query expression.
2. Filter and order before selecting a page
Apply the filter to the query, then apply the selected ordering, and only then select the page. This keeps pagination tied to the filtered and ordered result set. For reliable page boundaries when multiple rows share a sort value, consider adding a unique secondary ordering key.
Rank #2
3. Reset the page when a new search is submitted
A search can produce a smaller result set, so a page number that was valid before filtering may no longer exist. When the submitted search differs from the current filter, start at page one. For an unchanged filter, retain the requested page when it remains in range.
4. Return the page and render state-preserving links
Give the view the current filter and sort values along with the selected page and whatever metadata is needed to render navigation. Make each paging link carry the current filter and sort; change only the page number when the reader moves between pages. Make sortable column headings links that request the appropriate sort choice while retaining the filter.
Recommended Free Tools
Render the current page’s rows and provide previous, next, or numbered-page links appropriate to the helper or view code your application uses. Handle an empty result set and requests for pages beyond the available range deliberately; the classic MVC tutorial also demonstrates a zero-results display.
Use the ASP.NET Core MVC and EF Core pattern in Core applications
Microsoft’s ASP.NET Core MVC/EF Core tutorial uses an asynchronous paginated-list pattern. Its query applies Skip and Take so the database query returns the requested page rather than loading every row for the view. Its Razor view uses tag helpers for sort and page links.
Rank #4
Keep the framework patterns separate: the classic MVC tutorial’s helper and view syntax are not automatically interchangeable with ASP.NET Core MVC. Follow the APIs and conventions for the framework version your application actually targets.
Choose client-side or server-side pagination
| Consideration | Client-side table behavior | Server-side paging |
|---|---|---|
| Rows delivered to the browser | The browser needs the records it will sort and page. | The server returns the requested subset. |
| Where sorting and page selection happen | Browser code operates on the loaded rows. | The database-backed query is filtered and ordered before page selection. |
| Useful when | The result set is already loaded and browser interaction is the goal. | Limiting rows transferred and processed per request matters. |
| Who maintains navigation state | The client library manages interaction state unless it is synchronized with the URL or application state. | The controller and generated links preserve the sort, filter, and page parameters. |
Server-side paging is a practical choice when you want each request to return a bounded page; it does not require guessing a universal row-count cutoff. Microsoft’s EF Core tutorial demonstrates this with Skip and Take. A historical MSDN Magazine article from 2011 discusses jQuery DataTables as a client-side option and contrasts it with server-side paging in an Entity Framework and ASP.NET MVC 3 context. Treat that article as architectural background, not current plugin setup guidance.
Add jQuery table interaction where it fits
A jQuery table plugin can make sorting and paging interactive over rows already present in the page. This is a client-side arrangement: the browser can only sort and page the data it has received. If the server sends just one page, client-side pagination cannot navigate the complete result set unless the application also fetches other pages and coordinates that state.
The available Microsoft DataTables discussion is archival and does not establish current plugin APIs, versions, or compatibility. Before adding version-specific setup instructions to an application, check the current official documentation for the library you choose. Keep a clear division of responsibility: server-side filtering and paging belong in the request/query path; browser-side interactions operate on data already sent to the page.
Keep the table reliable as users navigate
- Preserve state: include the current sort and filter on page links, or navigation can discard the active ordering or search.
- Reset after a changed search: begin at page one so the new result set does not inherit an invalid page number.
- Order before paging: apply the selected sort before taking a page, and consider a unique secondary key to stabilize ties.
- Whitelist sort choices: map request values to known orderings instead of interpolating arbitrary input into dynamic query or SQL text.
- Handle boundary cases: render an intentional empty-results state and decide how the action responds to an out-of-range page.
ASP.NET Web Forms has separate paging behavior and controls; its GridView callback caveats are not requirements for an MVC/Razor table. Likewise, Microsoft’s Web Forms paging documentation warns qualitatively that default paging may retrieve all records for each page, which can become impractical for large result sets or many concurrent users. That is not a numeric benchmark for MVC implementations.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

