asp.net-mvc 无法将类型“System.Collections.Generic.List<string>”转换为“System.Web.Mvc.SelectList”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21464005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:29:38  来源:igfitidea点击:

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

asp.net-mvcasp.net-mvc-4html-helper

提问by john Gu

I have the following Action method, which have a viewBag with a list of strings:-

我有以下 Action 方法,它有一个带有字符串列表的 viewBag:-

public ActionResult Login(string returnUrl)
        {
            List<string> domains = new List<string>();
    domains.Add("DomainA");

            ViewBag.ReturnUrl = returnUrl;
            ViewBag.Domains = domains;
            return View();
        }

and on the view i am trying to build a drop-down list that shows the viewBag strings as follow:-

在视图中,我正在尝试构建一个下拉列表,显示 viewBag 字符串如下:-

@Html.DropDownList("domains",(SelectList)ViewBag.domains )

But i got the following error :-

但我收到以下错误:-

Cannot convert type 'System.Collections.Generic.List' to 'System.Web.Mvc.SelectList'

无法将类型“System.Collections.Generic.List”转换为“System.Web.Mvc.SelectList”

So can anyone adive why i can not populate my DropDown list of a list of stings ? Thanks

那么任何人都可以解释为什么我不能填充我的下拉列表的刺痛列表?谢谢

回答by Chris Pratt

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

因为DropDownList接受字符串列表。它接受IEnumerable<SelectListItem>. 您有责任将字符串列表转换为该列表。不过,这很容易:

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

Then, you can feed that to DropDownList:

然后,您可以将其提供给DropDownList

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

回答by dom

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

要完成 Chris Pratt 的回答,以下是一些用于创建下拉菜单的示例代码:

@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>

回答by Thanigainathan

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.

ViewBag 不是强类型的。您可以使用 ViewModel 类将实例传递给视图,以便视图可以使用多个数据源。

    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;}
    }

回答by user6683041

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

回答by vapcguy

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:

您确实需要为每个值设置一个“键”或索引,因为您必须将每个名称转换为IEnumerable<SelectListItem>,这需要一个 ID 值和一个文本字符串才能显示。您可以使用以下两种方法之一来做到这一点:

Use a Dictionary

使用字典

Make a Dictionary<int, string>:

做一个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 foreachon that list and use an indexer variable similar to what I show, below, instead of manually adding the items.

如果您有包含多个域的此信息的源列表,您可以foreach在该列表上执行 a并使用类似于我在下面显示的索引器变量,而不是手动添加项目。

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

您将需要一个模型。创建一个名为的类DomainViewModel.cs并将其添加到其中:

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:

然后遍历您的字典以将项目添加到 a DomainViewModel,然后将这些项目中的每一个添加到 a List<DomainViewModel>,类似于我在下一节中的内容,除了它看起来像这样:

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:

如果您不想使用 a Dictionary<>,您可以通过迭代List<string>并将其List<DomainViewModel>直接放入 a 来动态添加索引。以下是你将如何做到这一点:

1) Ensure you have created the DomainViewModel.csclass from above.

1) 确保您已经DomainViewModel.cs从上面创建了类。

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

2) 编辑您的控制器函数以构建您的List<string>,然后迭代它以使用索引器变量 ( )将其分块添加DomainViewModel到新List<DomainViewModel>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:

使用任一方法,一旦将其放入 a List<DomainViewModel>,您就可以执行以下操作:

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)