asp.net mvc - Cannot convert type 'System.Collections.Generic.List<string>' to 'System.Web.Mvc.SelectList'

ID : 274308

viewed : 18

Tags : asp.net-mvcasp.net-mvc-4html-helperasp.net-mvc





Top 5 Answer for asp.net mvc - Cannot convert type 'System.Collections.Generic.List<string>' to 'System.Web.Mvc.SelectList'

vote vote

96

Because DropDownList does not accept a list of strings. It accepts IEnumerable<SelectListItem>. It's your responsibility to convert your list of strings into that. This is easy enough though:

domains.Select(m => new SelectListItem { Text = m, Value = m }) 

Then, you can feed that to DropDownList:

@Html.DropDownList("domains", ((List<string>)ViewBag.domains).Select(m => new SelectListItem { Text = m, Value = m })) 
vote vote

86

To complete Chris Pratt's answer, here's some sample code to create the dropdown :

@Html.DropDownList("domains", new SelectList(((List<string>)ViewBag.domains).Select(d => new SelectListItem { Text = d, Value = d }), "Value", "Text")) 

Which will produce the following markup :

<select id="domains" name="domains">     <option value="item 1">item 1</option>     <option value="item 2">item 2</option>     <option value="item 3">item 3</option> </select> 
vote vote

80

ViewBag is not strongly typed. You can use ViewModel classes to pass instances to view so that view can utilize more than one data source.

    public ActionResult Login(string returnUrl)     {         List<string> domains = new List<string>();         domains.Add("DomainA");          ViewModel model=new ViewModel();         model.ReturnUrl = returnUrl;         model.Domains =new SelectList(domains);         return View(model);     }      Public Class ViewModel()     {         property Url ReturnUrl{get;set;}         property SelectList Domains{get;set;}     } 
vote vote

66

@Html.DropDownListFor(      m => m.Country,            new SelectList(_CountryList, "CountryID", "Title"),           new { @class = "form-control" } ) 
vote vote

54

You really need to have a "key", or index, for each value, because you have to convert each name to an IEnumerable<SelectListItem>, which requires an ID value and a Text string to display. You could do that using one of two ways:

Use a Dictionary

Make a Dictionary<int, string>:

Dictionary<int, string> domainDict = new Dictionary<int, string>(); 

and everytime you add a domain, you add a number:

domainDict.Add(1, "DomainA"); 

If you have a source list for this information with multiple domains, you could do a foreach on that list and use an indexer variable similar to what I show, below, instead of manually adding the items.

You will need a model. Create a class called DomainViewModel.cs and add this inside:

public class DomainViewModel() {     public int Id { get; set; }     public string Name { get; set; } } 

Then iterate over your dictionary to add the items to a DomainViewModel, and then add each of those items to a List<DomainViewModel>, similar to what I have below in the next section, except it would look like this:

List<DomainViewModel> lstDomainModel = new List<DomainViewModel>();  foreach(KeyValuePair<int, string> kvp in domainDict) {     DomainViewModel d = new DomainViewModel();     d.Id = kvp.Key;  // number      d.Name = kvp.Value;  // domain name     lstDomainModel.Add(d); } 

(Skip to Finishing Up, below)

List iteration with loop indexer

If you don't want to use a Dictionary<>, you could just add the index on the fly by iterating the List<string> and putting it into a List<DomainViewModel> directly. Here's how you would do that:

1) Ensure you have created the DomainViewModel.cs class from above.

2) Edit your controller function to build your List<string>, then iterate over it to add it in chunks of DomainViewModel to a new List<DomainViewModel> using an indexer variable (idx):

List<string> domains = new List<string>(); domains.Add("DomainA");  // etc.  List<DomainViewModel> lstDomainModel = new List<lstDomainModel>(); int idx = 0;  // Add your List<string> to your List<DomainViewModel> foreach (string s in domainList) {     DomainViewModel domainModel = new DomainViewModel();     domainModel.Id = idx;     domainModel.Name = s;     lstDomainModel.Add(domainModel);     idx++; } 

Finishing Up

Using either method, once you have it in a List<DomainViewModel>, you could do:

IEnumerable<SimpleListItem> domainList =      lstDomainModel.Select(d => new SelectListItem {              Text = d.Name,              Value = d.Id.ToString()          }     ); ViewBag.Domains = domainList; 

And show it in your view like this:

@Html.DropDownList("Domains", (IEnumerable<SelectListItem>)ViewBag.Domains) 

Top 3 video Explaining asp.net mvc - Cannot convert type 'System.Collections.Generic.List<string>' to 'System.Web.Mvc.SelectList'







Related QUESTION?