Back to: ASP.NET Core Tutorials For Beginners and Professionals
ListBox HTML Helper in ASP.NET Core MVC
In this article, I will discuss How to Generate a ListBox using ListBox HTML Helper in ASP.NET Core MVC Application with Examples. Please read our previous article discussing How to Generate Check Boxes using CheckBox HTML Helper in ASP.NET Core MVC.
What is a ListBox in Web Application?
A ListBox in web applications is an input element that allows users to select one or more items from a list displayed within a box. Users interact with a ListBox by clicking on the items it contains, which can be plain text or more complex elements depending on the application’s requirements.
Key Characteristics of a ListBox:
- Multiple Selections: A ListBox can be configured to allow users to select multiple items. This is typically achieved by holding down the Ctrl key while clicking to select or deselect individual items or using the Shift key to select a range of contiguous items.
- Scrollable: If the number of items exceeds the space available to display them, the ListBox can become scrollable, allowing users to navigate the list without changing its overall size.
- Single-Select and Multi-Select Modes: A ListBox can operate in single-select mode, where users can select only one item at a time, or multi-select mode, where users can select multiple items simultaneously (usually by holding down the Ctrl key or Shift key).
- HTML Structure: In HTML, a ListBox is created using the <select> element. Inside the <select> element, you can include one or more <option> elements, each representing an item in the list.
- Labeling and Values: Each <option> element can display text and a corresponding value. The value is sent to the server when the form is submitted.
Example of a Single Select ListBox in HTML:
<label for="fruits">Select a fruit:</label> <select id="fruits" name="selectedFruit"> <option value="apple">Apple</option> <option value="banana">Banana</option> <option value="orange">Orange</option> <option value="grape">Grape</option> </select>
Example of a Multi-Select ListBox in HTML:
<label for="colors">Select your favorite colors:</label> <select id="colors" name="selectedColors" multiple> <option value="red">Red</option> <option value="blue">Blue</option> <option value="green">Green</option> <option value="yellow">Yellow</option> </select>
In the Multi Select ListBox example, the multiple attribute on the <select> element enables users to select multiple elements at once.
How Do We Create a ListBox Using HTML Helper in ASP.NET Core MVC?
To create a ListBox using HTML Helpers in ASP.NET Core MVC, we need to use Html.ListBox or Html.ListBoxFor methods within our Razor views. The Html.ListBox method is used when you want to specify the name of the form field manually, while Html.ListBoxFor is used with model properties, providing a strongly typed approach. That means the ListBox() HTML Helper method is loosely typed, whereas the ListBoxFor() HTML Helper method is strongly typed.
What is ListBoxFor HTML Helper in ASP.NET Core MVC?
The ListBoxFor HTML helper in ASP.NET Core MVC is a server-side helper used to generate a <select> HTML element with the “multiple” attribute, allowing users to select multiple options from a list. The ListBoxFor helper is specifically designed to work with model properties. It is strongly typed, meaning it binds directly to model properties in your MVC application, ensuring compile-time checking of the property names you are binding to, which reduces the risk of errors.
Syntax: ListBoxFor<TResult>(Expression<Func<TModel, TResult>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes)
Explanation of Parameters:
expression: This parameter is a lambda expression that specifies the property in the model that will hold the selected values from the ListBox. It is strongly typed, which is tied to a specific model property. This allows the ListBoxFor helper to bind the selected values to this model property automatically.
selectList: This parameter provides the list of items rendered as options within the ListBox. Each item in this list is an instance of SelectListItem, which has the following properties:
- Value: The value of the option (e.g., the city ID).
- Text: The display text of the option (e.g., the city name).
- Selected: Indicates whether the option should be pre-selected.
htmlAttributes: This parameter passes additional HTML attributes to the ListBox element. These attributes are typically used for styling (e.g., adding CSS classes), adding IDs, setting sizes, or other standard HTML attributes. They are provided in an anonymous object format, where property names correspond to HTML attributes.
ListBoxFor HTML Helper Example in ASP.NET Core MVC:
Let us understand the ListBoxFor HTML helper method with an example. We need to generate the following list box, which allows the user to select multiple options.
We want the user to select one or more cities from the ListBox. Once the user selects the cities and clicks on the Submit button, we need to display the names of the selected cities separated by a comma. If the user doesn’t select any city and clicks on the Submit button, then the No Cities are Selected message should be displayed.
Creating Models:
First, we need to create a model that contains the list of items to be displayed in the ListBox and a property to hold the selected item(s). So, create a class file named City.cs within the Models folder and copy and paste the following code. The following model has three properties: CityId, CityName, and IsSelected.
namespace HTML_HELPER.Models { // This is a model class representing a City entity public class City { // Property representing the unique identifier for the City public int CityId { get; set; } // Property representing the name of the City public string CityName { get; set; } // Property indicating whether the City is selected (true or false) public bool IsSelected { get; set; } } }
Next, we need to create a View Model for use within the View. To do so, right-click on the Models folder and add a new class file named CitiesViewModel. Once you create the CitiesViewModel, copy and paste the following code. This class has two properties: SelectedCities and Cities.
namespace HTML_HELPER.Models { public class CitiesViewModel { // This will store a collection of selected city IDs (integers). public IEnumerable<int> SelectedCityIds { get; set; } // This will hold a collection of 'City' objects, representing the list of cities available for selection in the view. public IEnumerable<City> Cities { get; set; } } }
Modifying Home Controller:
Next, please modify the HomeController as follows. The following code is self-explained, so please read the comment lines for a better understanding:
using HTML_HELPER.Models; using Microsoft.AspNetCore.Mvc; using System.Text; namespace HTML_HELPER.Controllers { public class HomeController : Controller { // This method simulates fetching available cities from a data source, // which could be a database, an API, or hardcoded values as shown here private List<City> GetAvailableCities() { // Returns a list of City objects, each with a CityId, CityName, and IsSelected property return new List<City> { // Sample cities with their respective CityId, CityName, and a boolean IsSelected new City(){ CityId = 1, CityName = "London", IsSelected = false }, new City(){ CityId = 2, CityName = "New York", IsSelected = false }, new City(){ CityId = 3, CityName = "Sydney", IsSelected = true }, // Sydney is preselected new City(){ CityId = 4, CityName = "Mumbai", IsSelected = false }, new City(){ CityId = 5, CityName = "Cambridge", IsSelected = false }, new City(){ CityId = 6, CityName = "Delhi", IsSelected = true }, // Delhi is preselected new City(){ CityId = 7, CityName = "Hyderabad", IsSelected = false } }; } // This action method handles HTTP GET requests to the Index page [HttpGet] public ActionResult Index() { // Creating a CitiesViewModel instance to pass to the View CitiesViewModel citiesViewModel = new CitiesViewModel() { // Populates the Cities property of the ViewModel with the available cities from GetAvailableCities Cities = GetAvailableCities(), // Sets the SelectedCityIds property by selecting the CityIds of the cities that are preselected (IsSelected = true) SelectedCityIds = GetAvailableCities() .Where(city => city.IsSelected) // Filter cities that are marked as selected .Select(city => city.CityId) // Extract CityId of selected cities .ToList() // Convert the result to a List }; // Passes the populated ViewModel to the View for rendering return View(citiesViewModel); } // This action method handles HTTP POST requests when a form is submitted with selected cities [HttpPost] public string SubmittedCities(IEnumerable<int> SelectedCityIds) { // Check if no cities were selected (SelectedCityIds is null) if (SelectedCityIds == null) { // Return a message if no cities were selected return "No Cities Selected"; } else { // First, fetch the names of the cities that were selected using the CityId var CityNames = GetAvailableCities() .Where(t => SelectedCityIds.Contains(t.CityId)) // Filter cities by checking if their CityId is in the selected list .Select(item => item.CityName) // Extract the CityName of the selected cities .ToList(); // Convert the result to a List // Use StringBuilder to efficiently concatenate the city names into a single string StringBuilder sb = new StringBuilder(); // Append the selected city names, joining them with commas sb.Append("Your Selected City Names - " + string.Join(", ", CityNames)); // Return the final concatenated string of selected city names return sb.ToString(); } } } }
Modify the Index View:
Next, modify the Index.cshtml view file as follows. The following code is self-explained, so please read the comment lines for a better understanding:
@model HTML_HELPER.Models.CitiesViewModel @{ ViewBag.Title = "Index"; } <div> <form asp-action="SubmittedCities" asp-controller="Home" method="post"> @* The 'asp-action' attribute sets the action method that will handle the form submission ('SubmittedCities'). The 'asp-controller' attribute specifies the controller ('Home') that contains this action. The 'method="post"' defines that this form will submit data using the HTTP POST method. *@ <div class="form-group"> <label for="SelectedCityIds">Select Cities</label> @Html.ListBoxFor(m => m.SelectedCityIds, new MultiSelectList(Model.Cities, "CityId", "CityName"), new { @class = "form-control", size = 7 }) @* Generates a ListBox HTML element. The ListBoxFor binds the selected values to the 'SelectedCityIds' property in the model (m => m.SelectedCityIds). The 'MultiSelectList' takes the 'Cities' collection from the model, with 'CityId' as the value field and 'CityName' as the display field. Additional HTML attributes, like 'class' for Bootstrap styling ('form-control') and 'size' (showing 7 items at once), are passed to the ListBox element. *@ </div> <input type="submit" class="btn btn-primary" value="Submit" /> @* A submit button that sends the form data to the 'SubmittedCities' action in the 'Home' controller when clicked. *@ </form> </div>
Note: To select multiple items from the list box, hold down the CTRL Key. Run the application and see if everything is working as expected.
ListBox HTML Helper Method in ASP.NET Core MVC:
To use the ListBox HTML Helper, we need to specify the name of the form field and a list of items for the List Box. Optionally, you can also include HTML attributes to customize the appearance or behavior of the list box.
Syntax: ListBox(string expression, IEnumerable<SelectListItem> selectList, object htmlAttributes)
Parameters:
- expression: This parameter represents the name of the form field that will be used when the form is submitted.
- selectList: This is a collection of SelectListItem objects, each representing one selectable option within the <select> element. Each SelectListItem can have properties like Value, Text, and Selected:
-
- Value: The value that will be submitted if this option is selected.
- Text: The display text in the dropdown for the user.
- Selected: A boolean indicating whether this item should be pre-selected when the view is rendered.
-
- htmlAttributes: This parameter allows additional HTML attributes to be specified for the <select> element. These attributes can be provided as an anonymous object or a dictionary. For example, passing new { @class = “form-control”, size = 10 } would add a CSS class of form-control and set the size attribute of the select element to 10.
Example using ListBox HTML Helper in ASP.NET Core MVC:
Let us understand How we can use the ListBox HTML Helper in ASP.NET Core MVC Application, which is not a strongly typed HTML helper. We are going to do the same example using ListBox HTML Helper. So, modify the Home Controller class as follows.
using HTML_HELPER.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using System.Text; namespace HTML_HELPER.Controllers { public class HomeController : Controller { // This method simulates fetching available cities from a data source, // which could be a database, an API, or hardcoded values as shown here private List<City> GetAvailableCities() { // Returns a list of City objects, each with a CityId, CityName, and IsSelected property return new List<City> { new City(){ CityId = 1, CityName = "London", IsSelected = false }, new City(){ CityId = 2, CityName = "New York", IsSelected = false }, new City(){ CityId = 3, CityName = "Sydney", IsSelected = true }, // Sydney is preselected new City(){ CityId = 4, CityName = "Mumbai", IsSelected = false }, new City(){ CityId = 5, CityName = "Cambridge", IsSelected = false }, new City(){ CityId = 6, CityName = "Delhi", IsSelected = true }, // Delhi is preselected new City(){ CityId = 7, CityName = "Hyderabad", IsSelected = false } }; } // This action method handles HTTP GET requests to the Index page [HttpGet] public ActionResult Index() { // Prepare a list of SelectListItems for the ListBox var cities = GetAvailableCities().Select(city => new SelectListItem { Value = city.CityId.ToString(), // CityId will be used as the value of each ListBox item Text = city.CityName, // CityName will be displayed in the ListBox Selected = city.IsSelected // Preselect cities where IsSelected is true }).ToList(); // Pass cities to the view using ViewBag ViewBag.Cities = cities; return View(); } // This action method handles HTTP POST requests when a form is submitted with selected cities [HttpPost] public string SubmittedCities(IEnumerable<int> SelectedCityIds) { // Check if no cities were selected (SelectedCityIds is null) if (SelectedCityIds == null) { return "No Cities Selected"; } else { // Fetch the names of the cities that were selected using the CityId var CityNames = GetAvailableCities() .Where(t => SelectedCityIds.Contains(t.CityId)) // Filter cities by checking if their CityId is in the selected list .Select(item => item.CityName) // Extract the CityName of the selected cities .ToList(); // Convert the result to a List // Use StringBuilder to efficiently concatenate the city names into a single string StringBuilder sb = new StringBuilder(); // Append the selected city names, joining them with commas sb.Append("Your Selected City Names - " + string.Join(", ", CityNames)); // Return the final concatenated string of selected city names return sb.ToString(); } } } }
Next, modify the Index.cshtml file as follows:
@{ ViewBag.Title = "Index"; } <div> <form asp-action="SubmittedCities" asp-controller="Home" method="post"> <div class="form-group"> <label for="SelectedCityIds">Select Cities</label> @Html.ListBox("SelectedCityIds", (IEnumerable<SelectListItem>)ViewBag.Cities, new { @class = "form-control", size = 7 }) @* The first argument is the name ("SelectedCityIds") used for binding selected values in the POST action. The second argument is the IEnumerable<SelectListItem> (cast from ViewBag.Cities) that provides the items for the ListBox. Additional HTML attributes, like 'class' for Bootstrap styling ('form-control') and 'size' (showing 7 items at once), are passed. *@ </div> <input type="submit" class="btn btn-primary" value="Submit" /> </form> </div>
With the above changes in place, run the application, and you should get the expected output.
ListBoxFor Real-Time Example in ASP.NET Core MVC Application:
Let us understand this with an example. Imagine you are building an administration panel for a company where an admin needs to assign multiple roles (e.g., Admin, Editor, Viewer) to users. The roles are predefined and stored in the system. The admin can select multiple roles for a user from a ListBox, which will be assigned to the user. Let us proceed and implement this example step by step:
Define the Model
The model contains a list of roles available in the system and a list of selected role IDs for the user. So, create a class file named UserRoleViewModel.cs within the Models folder and then copy and paste the following code:
namespace HTML_HELPER.Models { public class UserRoleViewModel { public int UserId { get; set; } public string UserName { get; set; } public List<Role> AvailableRoles { get; set; } public List<int> SelectedRoleIds { get; set; } } public class Role { public int RoleId { get; set; } public string RoleName { get; set; } } }
Creating Admin Controller:
The controller will fetch the available roles, assign roles to a user, and handle the form submission. So, create an Empty MVC Controller named AdminController within the Controllers folder and then copy and paste the following code:
using HTML_HELPER.Models; using Microsoft.AspNetCore.Mvc; namespace HTML_HELPER.Controllers { public class AdminController : Controller { // This simulates fetching roles from a data source (e.g., database) private List<Role> GetAvailableRoles() { return new List<Role> { new Role { RoleId = 1, RoleName = "Admin" }, new Role { RoleId = 2, RoleName = "Editor" }, new Role { RoleId = 3, RoleName = "Viewer" } }; } public IActionResult AssignRoles(int userId = 1) { var model = new UserRoleViewModel { UserId = userId, UserName = "Pranaya Rout", // Example user AvailableRoles = GetAvailableRoles() }; return View(model); } [HttpPost] public IActionResult AssignRoles(UserRoleViewModel model) { // Repopulate the roles for the postback model.AvailableRoles = GetAvailableRoles(); if (model.SelectedRoleIds != null && model.SelectedRoleIds.Any()) { // Process selected roles and assign them to the user var assignedRoles = model.AvailableRoles .Where(role => model.SelectedRoleIds.Contains(role.RoleId)) .ToList(); // Display a message showing the assigned roles ViewBag.Message = $"Roles assigned to {model.UserName}: {string.Join(", ", assignedRoles.Select(r => r.RoleName))}"; } else { ViewBag.Message = "No roles selected."; } return View(model); } } }
Creating AssignRoles View
In the view, the ListBoxFor helper method displays the list of available roles the admin can select for the user. So, create a view named AssignRoles and then copy and paste the following code:
@model HTML_HELPER.Models.UserRoleViewModel @{ ViewData["Title"] = "AssignRoles"; } <h2>Assign Roles to @Model.UserName</h2> <form asp-action="AssignRoles" asp-controller="Admin" method="post"> @* This creates a form element that will post data to the "AssignRoles" action of the "Admin" controller. The method="post" specifies that the form data will be sent using an HTTP POST request, which is typically used for form submissions that modify data. *@ <div class="form-group"> <label for="Roles">Select Roles</label> @Html.ListBoxFor(m => m.SelectedRoleIds, new MultiSelectList(Model.AvailableRoles, "RoleId", "RoleName"), new { @class = "form-control" }) @* This helper creates a ListBox (multi-select list) for the property 'SelectedRoleIds' in the model. 'm => m.SelectedRoleIds' binds the ListBox to the 'SelectedRoleIds' property in the ViewModel. 'new MultiSelectList(Model.AvailableRoles, "RoleId", "RoleName")' populates the ListBox with a list of available roles from the model. 'RoleId' is used as the value for each option, and 'RoleName' is used as the displayed text. 'new { @class = "form-control" }' applies the 'form-control' CSS class to the ListBox, ensuring it uses Bootstrap styling. *@ </div> <button type="submit" class="btn btn-primary">Assign Roles</button> </form> @if (ViewBag.Message != null) { @* This checks if there is any message stored in the ViewBag "Message" property. If a message exists, it renders a Bootstrap alert box with that message. *@ <div class="alert alert-info"> @ViewBag.Message </div> }
Running the Application
When the admin navigates to the Admin/AssignRoles URL, they will see a list of available roles in a multiple-select list, as shown in the image below.
The admin can select one or more roles and click the “Assign Roles” button, as shown in the image below.
After submitting, the roles will be assigned to the user, and the assigned roles will be displayed in a confirmation message, as shown in the image below.
What are the Differences Between ListBox and ListBoxFor in ASP.NET Core MVC?
In ASP.NET Core MVC, ListBox and ListBoxFor are helper methods for rendering HTML <select> elements with multiple selection capabilities. However, they differ in how they bind to model data and how they are used within views. The following are the differences:
Binding to Model:
- ListBox: It does not automatically bind to a model property. You need to manually specify the name of the select element and pass the list of items you want to display. It is useful when we do not want to bind the selection directly to a model property.
- ListBoxFor: It binds directly to a model property. This helper method is strongly typed and takes an expression to identify the model property to which the ListBox will bind. When the form is submitted, the selected values are automatically bound to the model property.
Strongly Typed vs. Non-Strongly Typed:
- ListBox: Non-strongly typed helper method. It is not tied to a specific model property, so it is more flexible but requires more manual handling.
- ListBoxFor: Strongly typed helper method. Ensures that the ListBox is tied to a specific model property, reducing the chances of errors and making the code more maintainable.
Use Cases:
- ListBox: Suitable when you want to generate a list of selectable items without binding them to a model or when you need more control over how the data is handled.
- ListBoxFor: Suitable when you want to bind a list of items directly to a model property, making form processing more straightforward and streamlined.
In the next article, I will discuss the Editor HTML Helper in an ASP.NET Core MVC Application. In this article, I explain how to Create a ListBox using the ListBox HTML Helper in an ASP.NET Core MVC Application with Examples. I hope you enjoy this ListBox HTML Helper in an ASP.NET Core MVC article.