Using DataKeyNames in the ASP.NET GridView control

Posted by: Malcolm Sheridan , on 3/24/2009, in Category ASP.NET
Views: 82860
Abstract: The following article takes you through the basics on using DataKeyNames in the GridView control.
Using DataKeyNames in the ASP.NET GridView control
Recently I was asked by a work colleague about what was the best way to hide primary keys when displaying data in a GridView control. I mentioned the DataKeyNames property and got a blank stare. This little gem is a property on the GridView control that allows you to set an array that contains the primary key fields for the items displayed in a GridView control. 
Let’s get started. Open Visual Studio 2008 and create a new Web Application. This example won’t hook into a database, but we will create a class to mock a table and retrieve data from it instead. Right click on the project and choose Add > Class. Name the class Customer. Open the Customer class and add the following code:
public class Customer
public int ID { get; set; }
      public string GivenName { get; set; }
      public string Surname { get; set; }
      public string EmailAddress { get; set; }
      public string NickName { get; set; }
Public Class Customer
       Private privateID As Integer
       Public Property ID() As Integer
                   Return privateID
             End Get
             Set(ByVal value As Integer)
                   privateID = value
             End Set
       End Property
       Private privateGivenName As String
       Public Property GivenName() As String
                   Return privateGivenName
             End Get
             Set(ByVal value As String)
                   privateGivenName = value
             End Set
       End Property
       Private privateSurname As String
       Public Property Surname() As String
                   Return privateSurname
             End Get
             Set(ByVal value As String)
                   privateSurname = value
             End Set
       End Property
       Private privateEmailAddress As String
       Public Property EmailAddress() As String
                   Return privateEmailAddress
             End Get
             Set(ByVal value As String)
                   privateEmailAddress = value
             End Set
       End Property
       Private privateNickName As String
       Public Property NickName() As String
                   Return privateNickName
             End Get
             Set(ByVal value As String)
                   privateNickName = value
             End Set
       End Property
End Class
The Customer class contains five properties. The ID property is going to the unique identifier, so this is to be used internally by the application and should not be displayed to the user.
The next step is to create a collection of Customer objects and bind this to a GridView control. Open the Default.aspx page and the following code:
<asp:GridView ID="grdCustomer" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" onrowcommand="grdCustomer_RowCommand">
<asp:CommandField CausesValidation="false" ButtonType="Image" SelectImageUrl="~/Users.gif" ShowSelectButton="true" />
            <asp:BoundField DataField="GivenName" HeaderText="Name" />
<asp:BoundField DataField="Surname" HeaderText="Surname" />
            <asp:BoundField DataField="EmailAddress" HeaderText="Email" />
            <asp:BoundField DataField="NickName" HeaderText="Nick Name" />
In the code above the DataKeyNames property is set to the ID property. When data is bound to the GridView control, the GridView will look for a property named ID. When it is found, the value will be used as the primary key for each row in the GridView. This enables you to not display the ID to the user, yet still being able to retrieve it.  You can also assign multiple primary keys if desired by separating them with a comma (,). For example you could have the following code:
This means that now there are two primary key values defined; ID and Surname. A CommandField was also created in the code above. The ButtonType is set to Image, so for each row that is created in the GridView, an image will be displayed to the user. Clicking the image will raise the RowCommand event on the GridView. The purpose of doing this is to show you how to retrieve the DataKey value from the GridView control.
The next step is to create a collection of Customer objects and bind that to the GridView control. Open the Default.aspx page and add the following code:
protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
            List<Customer> customers = new List<Customer>();
            customers.Add(new Customer()
                  ID = 123,
                  GivenName = "Steve",
                  Surname = "Jobs",
                  EmailAddress = "",
                  NickName = "Steve"
            customers.Add(new Customer()
                  ID = 789,
                  GivenName = "Bill",
                  Surname = "Gates",
                  EmailAddress = "",
                  NickName = "Bill"
            grdCustomer.DataSource = customers;
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
       If (Not IsPostBack) Then
             Dim customers As New List(Of Customer)()
                  customers.Add(New Customer() With {.ID = 123, .GivenName = "Steve", .Surname = "Jobs", .EmailAddress = "", .NickName = "Steve"})
                  customers.Add(New Customer() With {.ID = 789, .GivenName = "Bill", .Surname = "Gates", .EmailAddress = "", .NickName = "Bill"})
                  grdCustomer.DataSource = customers
       End If
End Sub
In the code above, I have created a generic List<Customer> or List(Of Customer) to store the information. I have used a new feature to C# and VB.Net called Object Initialization. This allows you to create a new instance of a class and assign values to properties in one easy step.   Finally the code is bound to the GridView control by calling the DataBind method.
The last piece of code is to create an event handler for the RowCommand event. Open the Default.aspx page in the Design view. Select the GridView. Open the properties and select the lightning bolt to view the events for the GridView:
Grid Properties
 Double click the RowCommand event and Visual Studio will automatically create the event handler. Add the following code:
protected void grdCustomer_RowCommand(object sender, GridViewCommandEventArgs e)
object dataKeyValue = grdCustomer.DataKeys[int.Parse(e.CommandArgument.ToString())].Value;
Protected Sub grdCustomer_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
Dim dataKeyValue As Object =     grdCustomer.DataKeys(Integer.Parse(e.CommandArgument.ToString())).Value
End Sub
When the user selects a record from the grid, the selected row index will be passed through as the CommandArgument. Run the project and place a breakpoint on the code above. Select a row. The program will stop on the breakpoint and you will be able to see the selected row index being passed through. You can then use the code below to retrieve the ID value:
Data Key Names
The DataKeys property expects an integer. From there you can query the Value property to retrieve a single value, or you can query the Values property if you have an array of DataKeys defined.
Now that you have the primary key, you can go ahead and use it to lookup data from another table perhaps. DataKeyNames are a great way to use primary keys without having to display them to the user. If you have more than one primary key, you can separate the values with a comma. This adds extra flexibility to a great property.
The source code of this article in C# can be downloaded from here.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan

Page copy protected against web site content infringement 	by Copyscape

Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by kumarrupendra on Saturday, March 28, 2009 10:21 AM
It is very Good
Comment posted by msatyagupt on Wednesday, April 1, 2009 1:54 AM
Hi All,
I have a big problem for me bt little for you.

Suppose I have a XML file like

<Msg id="001" Value="This is first Message"></Msg>
<Msg id="002" Value="This is Second Message"></Msg>
<Msg id="003" Value="This is third Message"></Msg>

I want to display my all error message from XML file. So that any changes in message will reflect everywhere.

I want to read the Msg Value from a function whenever a pass its id, when i pass id 001 it will show "This is first message"

Help me,

Thanx in advance
Comment posted by santhosh on Saturday, April 25, 2009 9:14 AM
thank you, nice article.
Comment posted by kumar on Tuesday, June 9, 2009 12:54 PM
thanks very much
Comment posted by Prajeesh on Tuesday, June 9, 2009 2:21 PM
very helpful
Comment posted by Trouble with List not defined. on Friday, June 12, 2009 11:36 AM
I am trying to run the code, but I am having trouble with the Type 'List' is not defined.
Comment posted by Code To Popluate Not Working on Friday, June 12, 2009 12:09 PM
The code does not allow population of the GridView.
Comment posted by Malcolm Sheridan on Monday, August 3, 2009 7:32 PM
@ Code To Popluate Not Working
Have you downloaded the complete source code?
Comment posted by Jamie Gleeson on Monday, May 21, 2012 10:43 PM
Thanks for posting this, much appreciated
Comment posted by Bartholomew on Friday, August 16, 2013 5:11 AM
GridView Control for .NET
Comment posted by asdf on Friday, January 3, 2014 12:09 AM