没有类型为“ IEnumerable <SelectListItem>”的具有键“ xxx”的ViewData项目


87

关于Stack Overflow的文章有几篇,但没有一个答案似乎可以解决我目前的问题。

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

控制者

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

视图

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

我已经在很多地方使用了此设置,但是由于某种原因,在此特定视图中我得到了错误:

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


1
你有尝试过吗?<%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %>DropDownList需要IEnumerable<SelectListItem>
LukLed 2010年

@LukLed-的确是我最终找到错误原因的方法:)以及其他一些帖子中的信息!谢谢
Jimbo,2010年

<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>
阿维斯

今天遇到了这个问题,根据@jonathansewell的以下发现,我的DropDownList帮助器中的第二个参数为空。
肯·帕尔默

Answers:


79

好的,答案是从其他有关此问题的帖子中得出的,它是:

如果您ViewData包含的SelectList名称与您的名称相同,DropDownList即“ submarket_0”,则如果您未指定第二个参数(在本例中为源SelectList),则HTML帮助器会自动DropDownList使用该数据填充您的数据。

我的错误发生了什么:

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

如果我错了请指正我


104
我收到此错误是因为下拉列表的SelectListItems集合为空,这是您想到的相同问题。
乔纳森·瑟威尔

6
对于其他遇到此问题的用户,请暂时将您的下拉列表包装在null检查中,例如@if(ViewData [“ Submarkets”]!= null)。如果该视图随后呈现而没有引发错误(并且没有下拉列表),则将确定您的问题。在这种情况下,“无视图数据项”错误非常容易引起误解。
GDB 2014年

我遇到了这个Ajax.ActionLink。只需将添加SelectList GetActionMethod包含Ajax调用的即可。
臭2014年

是的 我已经更改了要从控制器传递到ViewData中的列表的名称,并且没有在视图中更改它。这是一个非常令人困惑的错误消息!
neminem 2014年

1
@JonathanSewell谢谢,谢谢,谢谢!这是我的确切问题。
johnw182

29

旧问题,但这是对该问题的另一种解释。即使您具有强类型的视图并且未使用ViewData创建下拉列表,您也会收到此错误。当您查看MVC源时,错误的原因可以变得很清楚:

// 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为null,MVC会在您的ViewData中查找命名的内容MyList,如果ViewData中没有该名称的对象,则会引发错误。


1
嗨,这也是我的问题,如果列表为空,该怎么办你能建议点什么吗
变压器

4
@transformer最简单的方法是将Model.DropDownData设置为空列表,而不是null。如果无法做到这一点,则可以更改剃刀标记以检查列表是否为空,如果是,则渲染一个空的选择列表。
霍克

15

我遇到了同样的错误,我认为问题是错误文本令人困惑,因为它给出了错误的键名。

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

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

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

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

希望这可以帮助!


9

问题是由于在单击提交按钮时发生了回发。因此,当在提交数据上发布数据时,请再次单击写入,然后再返回View()

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

3

检查命名空间。

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


1

也可以 例如:
==>在“ 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();

我们将看到此错误:

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

*因此,请确保这些语句存在。*


0

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


0

就我而言,我发现我错误地将post方法设置为private。在将私人变成公开之后。

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

改成

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

现在工作正常。


0

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


-1

就我而言,命名空间存在冲突,我有:

using System.Web.Mvc;

using System.Collections.Generic;

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

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

1
除非我的眼睛欺骗了我,否则一切都不会SelectList发生System.Collections.Generic
Erik Philips
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.