【问题标题】:Cannot convert type 'System.Collections.Generic.List<string>' to 'System.Web.Mvc.SelectList'无法将类型“System.Collections.Generic.List<string>”转换为“System.Web.Mvc.SelectList”
【发布时间】:2018-10-10 02:04:16
【问题描述】:

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

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

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

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

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

但我收到以下错误:-

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

那么任何人都可以告诉我为什么我不能填充我的 DropDown 列表的 stings 列表吗? 谢谢

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 html-helper


    【解决方案1】:

    因为DropDownList接受字符串列表。它接受IEnumerable&lt;SelectListItem&gt;。将您的字符串列表转换为该列表是您的责任。不过这很容易:

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

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

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

    【讨论】:

    • 还是得到'Cannot convert type 'System.Web.Mvc.SelectListItem[]' to 'System.Collections.Generic.List&lt;string&gt;''
    • @vapcguy:这里的代码假定ViewBag.domainsList&lt;string&gt;,因为它在OP 的问题中。听起来在您的情况下,ViewBag 成员已经是 IEnumerable&lt;SelectListItem&gt;,因此您应该改为使用它。
    • 是的,当我进入视图部分时,我不得不退出整个演员阵容:@Html.DropDownList("agency_id", (IEnumerable&lt;SelectListItem&gt;)ViewData["agency_id"]) 最终是我的样子。我在喂它:var agencies = db.AGENCIES.OrderBy(e =&gt; e.FULLNAME).ToList(); var agenciesList = agencies.Select(d =&gt; new SelectListItem { Text = d.FULLNAME, Value = d.AGENCY_ID.ToString() }); ViewData["agency_id"] = agenciesList;
    【解决方案2】:

    要完成 Chris Pratt 的回答,这里有一些创建下拉列表的示例代码:

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

    这将产生以下标记:

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

    【讨论】:

    • 您不需要创建SelectList 的实例。所有DropDownList 需要的是IEnumerable&lt;SelectListItem&gt;
    • List&lt;string&gt; 不包含Select 的定义,并且找不到接受List&lt;string&gt; 类型的第一个参数的扩展方法Select。我的应用程序是 MVC 5,也许自从这篇文章以来发生了一些变化?我不确定如何从视图页面引用程序集,这可能是我的问题吗?
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      @Html.DropDownListFor(
           m => m.Country, 
                new SelectList(_CountryList, "CountryID", "Title"),
                new { @class = "form-control" }
      )
      

      【讨论】:

      • 需要填写_CountryList的代码,这是一个适用的例子。除非很明显,否则不鼓励仅使用代码回答。
      【解决方案5】:

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

      使用字典

      创建Dictionary&lt;int, string&gt;:

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

      每次添加域时,都会添加一个数字:

      domainDict.Add(1, "DomainA");
      

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

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

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

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

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

      (跳至完成,如下)

      使用循环索引器进行列表迭代

      如果您不想使用Dictionary&lt;&gt;,您可以通过迭代List&lt;string&gt; 并将其直接放入List&lt;DomainViewModel&gt; 来即时添加索引。以下是你的做法:

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

      2) 编辑您的控制器函数以构建您的 List&lt;string&gt;,然后对其进行迭代以使用索引器变量 (idx) 将其以 DomainViewModel 的块添加到新的 List&lt;DomainViewModel&gt;

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

      完成

      使用任何一种方法,一旦你将它放在List&lt;DomainViewModel&gt; 中,你就可以这样做:

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

      并像这样在您的视图中显示它:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多