【问题标题】:There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'xxx'没有具有键 'xxx' 的 'IEnumerable<SelectListItem>' 类型的 ViewData 项
【发布时间】:2011-02-20 10:00:47
【问题描述】:

在 Stack Overflow 上有几篇关于此的帖子,但没有一个答案似乎可以解决我当前情况下的问题。

我有一个页面,其中有一个表格,每一行都有一些文本字段和一个下拉列表。所有的下拉菜单都需要使用相同的 SelectList 数据,所以我设置如下:

控制器

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");

查看

<%= Html.DropDownList("submarket_0", (SelectList)ViewData["Submarkets"], "(none)") %>

我在很多地方都使用过这个设置,但由于某种原因,在这个特定的视图中我得到了错误:

没有具有键“submarket_0”的“IEnumerable”类型的 ViewData 项。

【问题讨论】:

  • 你试过了吗? &lt;%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %&gt; DropDownList 采用 IEnumerable&lt;SelectListItem&gt;
  • @LukLed - 这确实是我最终找到错误来源的方式:) 以及来自其他一些帖子的信息!谢谢
  • &lt;%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable&lt;SelectListItem&gt;, "(none)") %&gt;
  • 今天遇到这个问题,发现我的 DropDownList 助手中的第二个参数为空,根据@jonathansewell 的以下发现。

标签: asp.net-mvc ienumerable drop-down-menu viewdata selectlist


【解决方案1】:

好的,所以答案来自关于这个问题的其他一些帖子,它是:

如果您的ViewData 包含与您的DropDownList 同名的SelectList,即“submarket_0”,则 Html 帮助程序将自动使用该数据填充您的DropDownList如果您没有指定第二个参数,在这种情况下是源 SelectList。

我的错误发生了什么:

因为包含下拉列表的表格位于部分视图中,并且 ViewData 已更改并且不再包含我引用的 SelectList,所以 HtmlHelper(而不是抛出错误)试图找到在它仍然找不到的 ViewData (GRRRR !!!) 中名为“submarket_0”的 SelectList,然后在上面抛出了一个错误:)

如有错误请指正

【讨论】:

  • 我收到此错误是因为我为下拉列表收集的 SelectListItems 为空,我认为这与您遇到的问题相同。
  • 对于遇到此问题的其他人,暂时将您的下拉列表包含在一个空检查中,例如@if (ViewData["Submarkets"] != null)。如果视图随后呈现而没有引发错误(并且没有您的下拉列表),您将确定您的问题。在这种情况下,“无视图数据项”错误非常具有误导性。
  • 我使用Ajax.ActionLink 遇到了这个问题。只需将 SelectList Get 添加到包含 Ajax 调用的 ActionMethod 即可。
  • 是的!我更改了从控制器传递到 ViewData 的列表的名称,并没有在视图中更改它。这是一个非常令人困惑的错误消息!
  • @JonathanSewell 谢谢,谢谢,谢谢!这正是我的问题。
【解决方案2】:

老问题,但这是对问题的另一种解释。即使您有强类型视图并且没有使用 ViewData 创建下拉列表,您也会收到此错误。当您查看MVC source 时,错误的原因就会变得清晰:

// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
    selectList = htmlHelper.GetSelectData(name);
    usedViewData = true;
}

所以如果你有类似的东西:

@Html.DropDownList("MyList", Model.DropDownData, "")

Model.DropDownData 为空,MVC 会在您的 ViewData 中查找名为 MyList 的内容,如果 ViewData 中没有具有该名称的对象,则会引发错误。

【讨论】:

  • 您好,这也是我的问题,如果列表为空,我们该怎么办!您能提出一些建议吗,
  • @transformer 最简单的做法是将 Model.DropDownData 设置为空列表而不是 null。如果这不可能,您可以更改您的 razor 标记以检查列表是否为空,如果是,则呈现一个空的选择列表。
【解决方案3】:

我有同样的错误,我认为问题在于错误文本令人困惑,因为它给出了一个错误的键名。

在您的情况下,它应该说“没有类型为 'IEnumerable' 且具有键“子市场”的 ViewData 项目”。

我的错误是视图代码(您的“子市场”)中的拼写错误,但错误文本让我发疯了。

我发布这个答案是因为我想说寻找这个错误的人,就像我一样,问题是 它没有找到 IENumerable,而是在它应该寻找它的 var 中(“子市场" 在这种情况下),而不是显示错误的那个(“submarket_0”)

接受的答案非常有趣,但是正如您所说,如果您不指定第二个参数,则应用约定,在这种情况下,它已指定,但未找到 var(在您的情况下,因为 viewdata 没有它,在我的情况是因为我拼错了 var 名称)

希望这会有所帮助!

【讨论】:

    【解决方案4】:

    问题是因为在提交按钮单击时发生了回发。 因此,在提交点击时发布数据 在返回 View() 之前再次写入

    ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
    

    【讨论】:

      【解决方案5】:

      检查命名空间。

      您可以在控制器中分配 System.Web.Webpages.Html.SelectListItem,而不是 System.Web.Mvc.SelectListItem

      【讨论】:

        【解决方案6】:

        这也可以;例如:
        ==> 在“NumberController”文件中:

        public ActionResult Create([Bind(Include = "NumberId,Number1,Number2,OperatorId")] Number number)
        {
            if (ModelState.IsValid)
            {
                ...
                ...
                return RedirectToAction("Index");
            }
            ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", 
                                        "OperatorSign", number.OperatorId);                
            return View();
        }
        

        ==> 在视图文件(Create.cshtml)中:

        <div class="form-group">
            @Html.LabelFor(model => model.Number1, htmlAttributes: new { @class = 
                           "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Number1, new { htmlAttributes = new { 
                                @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Number1, "", new { @class = 
                                           "text-danger" })
            </div>
        </div>
        

        现在,如果我们删除此声明:

        ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId);
        

        从以下语句的后面(在我们的控制器中):

        return View();
        

        我们会看到这个错误:

        没有具有键“OperatorId”的“IEnumerable”类型的 ViewData 项。

        * 所以请确保这些陈述的存在。 *

        【讨论】:

          【解决方案7】:

          对我来说,当我将新行保存到数据库时出现了导致此错误的问题,但字段为空。在数据库表设计中,该字段不为空。因此,当我尝试为非空字段保存一个空值的新行时,Visual Studio 抛出了这个错误。因此,我确保为该字段分配了一个值,并且问题已得到解决。

          【讨论】:

            【解决方案8】:

            就我而言,我发现我错误地将 post 方法设置为私有。将私有更改为公共之后。

            [HttpPost]
            private async Task<ActionResult> OnPostRemoveForecasting(){}
            

            改成

            [HttpPost]
            public async Task<ActionResult> OnPostRemoveForecasting(){}
            

            现在可以正常工作了。

            【讨论】:

              【解决方案9】:

              原因并非违反语法,而是对象使用不当。 ViewData、ViewBag 和 View Life Cycle 中对象的生命周期比会话中的要短。前者定义的数据在请求-响应后会丢失(如果在请求-响应后尝试访问,则会出现异常)。所以前者适合在 View & Controller 之间传递数据,而后者适合存储临时数据。临时数据应该存储在会话中,以便可以多次访问。

              【讨论】:

                【解决方案10】:

                在我的情况下,命名空间有冲突,我有:

                using System.Web.Mvc;
                

                using System.Collections.Generic;
                

                我明确地想使用 Mvc,所以我将它声明为:

                new System.Web.Mvc.SelectList(...)
                

                【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-04-26
                • 2020-06-28
                • 2020-08-20
                • 2015-03-11
                • 1970-01-01
                相关资源
                最近更新 更多