ASP.NET MVC DropDownListFor with model of type List<string>

C#asp.net Mvcasp.net Mvc-3RazorHtml Helper

C# Problem Overview


I have a view with a model of type List<string> and I want to place a drop down list on the page that contains all strings from the list as items in the drop down. I am new to MVC, how would I accomplish this?

I tried this:

@model List<string>
@Html.DropDownListFor(x => x)

but that threw an error.

C# Solutions


Solution 1 - C#

To make a dropdown list you need two properties:

  1. a property to which you will bind to (usually a scalar property of type integer or string)
  2. a list of items containing two properties (one for the values and one for the text)

In your case you only have a list of string which cannot be exploited to create a usable drop down list.

While for number 2. you could have the value and the text be the same you need a property to bind to. You could use a weakly typed version of the helper:

@model List<string>
@Html.DropDownList(
    "Foo", 
    new SelectList(
        Model.Select(x => new { Value = x, Text = x }),
        "Value",
        "Text"
    )
)

where Foo will be the name of the ddl and used by the default model binder. So the generated markup might look something like this:

<select name="Foo" id="Foo">
    <option value="item 1">item 1</option>
    <option value="item 2">item 2</option>
    <option value="item 3">item 3</option>
    ...
</select>

This being said a far better view model for a drop down list is the following:

public class MyListModel
{
    public string SelectedItemId { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

and then:

@model MyListModel
@Html.DropDownListFor(
    x => x.SelectedItemId,
    new SelectList(Model.Items, "Value", "Text")
)

and if you wanted to preselect some option in this list all you need to do is to set the SelectedItemId property of this view model to the corresponding Value of some element in the Items collection.

Solution 2 - C#

If you have a List of type string that you want in a drop down list I do the following:

EDIT: Clarified, making it a fuller example.

public class ShipDirectory
{
    public string ShipDirectoryName { get; set; }
    public List<string> ShipNames { get; set; }
}

ShipDirectory myShipDirectory = new ShipDirectory()
{
    ShipDirectoryName = "Incomming Vessels",
    ShipNames = new List<string>(){"A", "A B"},
}

myShipDirectory.ShipNames.Add("Aunt Bessy");

@Html.DropDownListFor(x => x.ShipNames, new SelectList(Model.ShipNames), "Select a Ship...", new { @style = "width:500px" })

Which gives a drop down list like so:

<select id="ShipNames" name="ShipNames" style="width:500px">
    <option value="">Select a Ship...</option>
    <option>A</option>
    <option>A B</option>
    <option>Aunt Bessy</option>
</select>

To get the value on a controllers post; if you are using a model (e.g. MyViewModel) that has the List of strings as a property, because you have specified x => x.ShipNames you simply have the method signature as (because it will be serialised/deserialsed within the model):

>public ActionResult MyActionName(MyViewModel model)

>Access the ShipNames value like so: model.ShipNames

If you just want to access the drop down list on post then the signature becomes:

>public ActionResult MyActionName(string ShipNames)

EDIT: In accordance with comments have clarified how to access the ShipNames property in the model collection parameter.

Solution 3 - C#

I realize this question was asked a long time ago, but I came here looking for answers and wasn't satisfied with anything I could find. I finally found the answer here:

https://www.tutorialsteacher.com/mvc/htmlhelper-dropdownlist-dropdownlistfor

To get the results from the form, use the FormCollection and then pull each individual value out by it's model name thus:

yourRecord.FieldName = Request.Form["FieldNameInModel"];

As far as I could tell it makes absolutely no difference what argument name you give to the FormCollection - use Request.Form["NameFromModel"] to retrieve it.

No, I did not dig down to see how th4e magic works under the covers. I just know it works...

I hope this helps somebody avoid the hours I spent trying different approaches before I got it working.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChevView Question on Stackoverflow
Solution 1 - C#Darin DimitrovView Answer on Stackoverflow
Solution 2 - C#Paul ZahraView Answer on Stackoverflow
Solution 3 - C#DaveN59View Answer on Stackoverflow