Application Security Testing: An Integral Part of DevOps
As a web developer, you may have come across situations in which you wish you were not stuck with the default paging system provided with the ASP.NET DataGrid. But, at the same time, not having to write a custom DataGrid control or relying on a third-party DataGrid control would have made life much easier.
The simplest way to overcome this would be, quite simply, to have your own paging control, which you can use in conjunction with the existing DataGrid. In this article, I will show you how to write a custom paging control, such as (but definitely not limited to) the one shown here:
In the image shown above, note that the blue 'footer' bar and the paging navigation controls below it are what constitute the paging control. The rest of it is simply the ASP.NET DataGrid.
And now, you start. You will be:
- Creating the paging control
- Creating a simple webform to use the control
- Creating a stored procedure that allows paging
1. Creating the Paging Control
Because you want to make this as customizable as possible, you will create a web user control. In Visual Studio, add a new web user control to your project and name it PagingControl.ascx.
On this page, create a table with two rows. In the first row, place a centered label that will display the current page number; in the second row, place three labels, a textbox, and a button for the purpose of paging navigation. You are not limited, of course, to the textbox;you even can have a dropdown there, but for the sake of simplicity, just use a textbox.
<table cellSpacing="0" cellPadding="0" width="100%" border="0"> <tr> <td align="center" id="tdFooterDisplay" runat="server" height="5"> <asp:Label ID="lblCurrentPageNumber" Runat="server"></asp:Label> </td> </tr> <tr> <td align="right"> <asp:label id="lblPage" Runat="server"></asp:label> & <asp:textbox id="txtPageNumber" Runat="server" Width="20"></asp:textbox> & <asp:label id="lblOf" Runat="server"></asp:label> & <asp:label id="lblTotalPages" Runat="server"></asp:label> <asp:button id="btnGo" Runat="server"></asp:button> <!-- We need to ensure that only numbers are entered --> <asp:RegularExpressionValidator Text="*" ControlToValidate="txtPageNumber" id="rePageNumber" runat="server" ValidationExpression="\d+"></asp:RegularExpressionValidator> <!-- We need to ensure that the textbox is not left blank --> <asp:RequiredFieldValidator Text="*" ControlToValidate="txtPageNumber" ID="rqPageNumber" Runat="server"></asp:RequiredFieldValidator> </td> </tr> </table>
You now create the code to make this control work. Of importance will be the event you must raise so that it can be handled on the web page that will use this control. Start by declaring a delegate and an event for it.
Public Delegate Sub PageChangedEventHandler(ByVal sender As Object, _ ByVal e As DataNavigatorEventArgs) Public Event PageChanged As PageChangedEventHandler
Create a sub that will do the actual raising of the event.
Protected Sub OnPageChanged(ByVal args As DataNavigatorEventArgs) RaiseEvent PageChanged(Me, args) End Sub
Notice that this sub expects an object of type DataNavigatorEventArgs. This object will contain information pertinent to navigation, so you will come to this later. Because the 'Go' button in your control is what will raisw the event, you write that as well.
Private Sub btnGo_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnGo.Click Dim args As New DataNavigatorEventArgs args.CurrentPage = Integer.Parse(Me.txtPageNumber.Text) args.TotalPages = Integer.Parse(Me.lblTotalPages.Text) OnPageChanged(args) Me.lblCurrentPageNumber.Text = args.CurrentPage.ToString() End Sub
The purpose of DataNavigatorEventArgs should be clearer by now, and so should its structure. Add a class to your solution, called DataNavigatorEventArgs, and place this code there.
Public Class DataNavigatorEventArgs Inherits EventArgs Private m_iCurrentPage As Integer Private m_iTotalPages As Integer Public Sub New() End Sub Public Property CurrentPage() As Integer Get Return m_iCurrentPage End Get Set(ByVal Value As Integer) m_iCurrentPage = Value End Set End Property Public Property TotalPages() As Integer Get Return m_iTotalPages End Get Set(ByVal Value As Integer) m_iTotalPages = Value End Set End Property End Class
To make your control more developer friendly, you also expose a few properties for specifying the current page, the total number of pages, CSS class names to use, and so on. These properties are given values in the page load event for the control. You can find the rest of the code for PagingControl.ascx.vb in the sample accompanying this article, but a few important properties are shown here.
Public Property CurrentPage() As Integer Get Return _intCurrentPage End Get Set(ByVal Value As Integer) _intCurrentPage = Value End Set End Property Public Property TotalPages() As Integer Get Return _intTotalPages End Get Set(ByVal Value As Integer) _intTotalPages = Value End Set End Property
The control is now ready.