2 minute read

4 min read 840 words

1. Introduction

In web applications, we often need to present users with a list of options to choose from. In ASP.NET Core MVC, the SelectList class is the standard way to prepare data for a <select> dropdown element.

Whether you are hardcoding a few options or pulling thousands of records from a database, understanding how to construct and bind a SelectList is essential for building robust forms.


2. The Basics: SelectListItem

At its core, a SelectList is a collection of SelectListItem objects. Each SelectListItem represents one <option> in the final HTML and has three main properties:

  • Text: What the user sees in the dropdown.
  • Value: What is sent to the server when the form is submitted.
  • Selected: A boolean indicating if this option should be selected by default.

3. Creating a SelectList in the Controller

You usually prepare your list in the Controller and pass it to the View.

A. Static Data

public IActionResult Create()
{
    var categories = new List<SelectListItem>
    {
        new SelectListItem { Value = "1", Text = "Electronics" },
        new SelectListItem { Value = "2", Text = "Books" },
        new SelectListItem { Value = "3", Text = "Clothing" }
    };

    ViewBag.Categories = new SelectList(categories, "Value", "Text");
    return View();
}

B. Dynamic Data (From a Database)

When using a database, you typically have a collection of objects. The SelectList constructor allows you to specify which properties should be used for the value and the text.

public async Task<IActionResult> Edit(int id)
{
    var product = await _context.Products.FindAsync(id);
    var brands = await _context.Brands.ToListAsync();

    // Syntax: new SelectList(items, dataValueField, dataTextField, selectedValue)
    ViewBag.BrandId = new SelectList(brands, "Id", "Name", product.BrandId);

    return View(product);
}

4. Passing Data to the View

Using a ViewModel is cleaner and provides type safety.

public class ProductViewModel
{
    public int SelectedBrandId { get; set; }
    public SelectList BrandList { get; set; }
}

ViewBag/ViewData

Useful for simple scenarios or when you don’t want to modify your ViewModel.

ViewBag.Categories = new SelectList(categories, "Id", "Name");

5. Using it in Razor (The Select Tag Helper)

The asp-items attribute is used to bind the list to the <select> tag.

@model ProductViewModel

<div class="form-group">
    <label asp-for="SelectedBrandId">Brand</label>
    <select asp-for="SelectedBrandId" 
            asp-items="Model.BrandList" 
            class="form-control">
        <option value="">-- Select Brand --</option>
    </select>
    <span asp-validation-for="SelectedBrandId" class="text-danger"></span>
</div>

If using ViewBag:

<select asp-for="BrandId" asp-items="ViewBag.BrandId" class="form-control"></select>

6. Multi-Select Lists

If you need the user to select multiple options, use MultiSelectList and an array/list in your model.

Controller:

var tags = _context.Tags.ToList();
ViewBag.Tags = new MultiSelectList(tags, "Id", "Name", selectedTagIds);

View:

<select asp-for="SelectedTagIds" asp-items="ViewBag.Tags" class="form-control" multiple>
</select>

7. Best Practices

  1. Keep Logic in Controller/Service: Don’t query the database inside your Razor view to build a list.
  2. Use ViewModels: It makes your views easier to test and maintain.
  3. Include a Default Option: Use a hardcoded <option value="">Select...</option> inside the <select> tag; the Tag Helper will prepend it to the items from asp-items.
  4. Enum Support: For enums, you can use the Html.GetEnumSelectList<TEnum>() helper directly in the view.

Leave a comment