Search code examples
c#asp.net-mvcrazorasp.net-core-mvchtml.dropdownlistfor

Populate a dropdown list via controller action


I have to populate a dropdown list from a List<string> where the key is equal to the displayed value. I came up to extract the values, I did various tests to connect to the View but without success. Given the code that extracts the values:

public async Task<IActionResult> PopulateDropDownList()
{
    try
    {
        var items = await DocumentDBRepository<CosmosDBTelemetry>.GetDeviceIds();
        List<string> deviceids = new List<string>();

        foreach(var item in items)
        {
            deviceids.Add(item.deviceId);
        }

        return View();
      }
      catch (Exception e)
      {
        throw (e);
     }
}

Can anyone help me for the rest?


Solution

  • In a Model-View-Controller (MVC) framework, it is the job of the controller to pass the model to the view. Assuming that your list of strings, items, is correctly populated, the controller needs to pass it to the view.

    First, you need to distinguish between actions and helper methods. Actions are public methods in the controller class. Actions can be accessed by the user via URL so in your case, http://application_name/controller_name/PopulateDropDownList would be a valid URL although this is meaningless to the user. Instead, you need to make PopulateDropDownList into a helper method like so:

    private async Task<IEnumerable<string>> GetDropdownOptionsList()
    {
      List<string> items = ...;
      return items;
    }
    

    Then, call the helper from a URL action such as

    public async Task<IActionResult> View()
    {
      List<string> items = await GetDropdownListOptions();
      return View(items);
    }
    

    You may wish to look at this documentation for information on controller actions.

    Second, the View() method constructs the view and sends it to the user but by default, it passes no data. You can pass your list of strings to the view by calling View(items) instead of View(). Then, your view would look like:

    @model IEnumerable<string>
    
    <select>
      @foreach (string item in Model)
      {
        <option value="@item">@item</option>
      }
    </select>
    

    The @model IEnumerable<string> directive specifies that the view expects a list of strings to be passed into the view. The @foreach (string item in Model) iterates through each string in the list and generates an option element for each one.

    If you need to pass multiple data models into the view, you could use the ViewBag or ViewData objects. Simply add ViewBag.Items = items; to your PopulateDropDownList method like so:

    private async void PopulateDropDownList()
    {
      List<string> items = ...;
      ViewBag.Items = items;
    }
    

    Then your view would look like:

    <select>
      @foreach (string item in (IEnumerable<string>)ViewBag.Items)
      {
        <option value="@item">@item</option>
      }
    </select>
    

    I hope this helps!