ASP.NET

Bind an ASP.NET DropDownList to SQL Server data (C#)

ASP.NET · · Published 2026-09-15

Filling a drop-down list from a database table is one of the first things every Web Forms developer writes. Three properties do the work: DataSource, DataTextField and DataValueField. The details that make it correct are the placeholder item, binding only once, and validating the choice.

Markup

<asp:Label runat="server" AssociatedControlID="ddlCategory" Text="Category" />
<asp:DropDownList ID="ddlCategory" runat="server" AppendDataBoundItems="true">
    <asp:ListItem Value="" Text="-- choose a category --" />
</asp:DropDownList>
<asp:RequiredFieldValidator runat="server" ControlToValidate="ddlCategory" InitialValue=""
    ErrorMessage="Please choose a category." Display="Dynamic" />
<asp:Button ID="btnNext" runat="server" Text="Next" OnClick="btnNext_Click" />

AppendDataBoundItems="true" keeps the static placeholder and appends the database rows after it. The validator's InitialValue="" makes the placeholder count as "nothing chosen".

Code-behind

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        BindCategories();
    }
}

private void BindCategories()
{
    string cs = ConfigurationManager.ConnectionStrings["Db"].ConnectionString;
    using (var con = new SqlConnection(cs))
    using (var cmd = new SqlCommand("SELECT CategoryId, Name FROM dbo.Categories WHERE Active = 1 ORDER BY Name", con))
    {
        con.Open();
        using (SqlDataReader r = cmd.ExecuteReader())
        {
            ddlCategory.DataSource = r;
            ddlCategory.DataTextField = "Name";        // what the user sees
            ddlCategory.DataValueField = "CategoryId"; // what is posted
            ddlCategory.DataBind();
        }
    }
}

protected void btnNext_Click(object sender, EventArgs e)
{
    if (!IsValid) return;
    int categoryId = int.Parse(ddlCategory.SelectedValue);
    string categoryName = ddlCategory.SelectedItem.Text;
    // ...
}

Binding inside if (!IsPostBack) matters: the list keeps its items across postbacks through view state, and rebinding in every Page_Load would reset the user's selection before btnNext_Click reads it. If you must rebind (for example after adding a category), call ddlCategory.Items.Clear() first and re-add the placeholder, or the items accumulate because of AppendDataBoundItems.

Binding to a reader works because the list enumerates it once during DataBind, while the connection is still open.

Variations

Common mistakes

Official documentation