There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'xxx'
Asked Answered
T

10

87

There are a couple of posts about this on Stack Overflow but none with an answer that seem to fix the problem in my current situation.

I have a page with a table in it, each row has a number of text fields and a dropdown. All the dropdowns need to use the same SelectList data so I have set it up as follows:

Controller

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

View

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

I have used exactly this setup in many places, but for some reason in this particular view I get the error:

There is no ViewData item of type 'IEnumerable' that has the key 'submarket_0'.

Tombolo answered 17/5, 2010 at 13:22 Comment(4)
Did you try this? <%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %> DropDownList takes IEnumerable<SelectListItem>.Metamorphic
@Metamorphic - that is indeed how I eventually found the source of the error :) as well as information from some other posts! ThanksTombolo
<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>Galle
Encountered this today and found the second argument in my DropDownList helper was null, per the finding below from @jonathansewell.Fuscous
T
81

Ok, so the answer was derived from some other posts about this problem and it is:

If your ViewData contains a SelectList with the same name as your DropDownList i.e. "submarket_0", the Html helper will automatically populate your DropDownList with that data if you don't specify the 2nd parameter which in this case is the source SelectList.

What happened with my error was:

Because the table containing the drop down lists was in a partial view and the ViewData had been changed and no longer contained the SelectList I had referenced, the HtmlHelper (instead of throwing an error) tried to find the SelectList called "submarket_0" in the ViewData (GRRRR!!!) which it STILL couldnt find, and then threw an error on that :)

Please correct me if im wrong

Tombolo answered 17/5, 2010 at 14:8 Comment(6)
I got this error because my collection of SelectListItems for the drop down list was null, which is the same problem you had I think.Cootch
For others confronted with this problem, temporarily wrap your drop down list in a null check, e.g. @if (ViewData["Submarkets"] != null). If the view then renders without throwing an error (and without your drop down list) you will have identified your problem. The "no view data item" error is very misleading in this case.Privative
I ran into this using an Ajax.ActionLink. Just add the SelectList Get to the ActionMethod that contains the Ajax call.Agnola
Yep! I'd changed the name of the list I was passing into the ViewData from the controller, and hadn't changed it in the view. That is a really terribly confusing error message!Manufacturer
@JonathanSewell thank you, thank you, thank you! This was my exact problem.Scrawny
Yes in my case, i simply added Viewbag assingment in wrong method.Epigraphic
L
30

Old question, but here's another explanation of the problem. You'll get this error even if you have strongly typed views and aren't using ViewData to create your dropdown list. The reason for the error can becomes clear when you look at the 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;
}

So if you have something like:

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

And Model.DropDownData is null, MVC looks through your ViewData for something named MyList and throws an error if there's no object in ViewData with that name.

Lur answered 11/10, 2013 at 20:10 Comment(2)
Hi, this is my problem too, What do we do if the list is null! can you suggest something,Hygienist
@transformer The easiest thing to do would be to set Model.DropDownData to an empty list instead of null. If that isn't possible, you could alter your razor markup to check if the list is null, and if so, render an empty select list.Lur
S
15

I had same error, I think the problem is that the error text is confusing, because its giving a false key name.

In your case It should say "There is no ViewData item of type 'IEnumerable' that has the key "Submarkets"".

My error was a misspelling in the view code (your "Submarkets"), but the error text made me go crazy.

I post this answer because I want to say people looking for this error, like I was, that the problem is that its not finding the IENumerable, but in the var that its supposed to look for it ("Submarkets" in this case), not in the one showed in error ("submarket_0").

Accepted answer is very interesting, but as you said the convention is applied if you dont specify the 2nd parameter, in this case it was specified, but the var was not found (in your case because the viewdata had not it, in my case because I misspelled the var name)

Hope this helps!

Squirearchy answered 28/10, 2011 at 7:38 Comment(0)
D
9

The problem is because of post back happens on submit button click. So while posting data on submit click again write before returning View()

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");
Duvall answered 5/9, 2011 at 7:29 Comment(0)
F
3

Check the Namespace.

You might assign System.Web.Webpages.Html.SelectListItem in the Controller, instead of System.Web.Mvc.SelectListItem.

Fear answered 22/5, 2013 at 9:28 Comment(0)
M
1

This is OK too; For example:
==> In "NumberController" file:

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

==> In View file (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>

Now if we remove this statement:

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

from back of the following statement (in our controller) :

return View();

we will see this error:

There is no ViewData item of type 'IEnumerable' that has the key 'OperatorId'.

* So be sure of the existing of these statements. *

Milagrosmilam answered 8/10, 2017 at 12:46 Comment(0)
O
0

For me, the problem that caused this error arose when I was saving a new row to the database, but a field was null. In the database table design, that field is NOT NULL. So when I tried to save a new row with a null value for not-null field, Visual Studio threw this error. Thus, I made sure that the field was assigned a value, and the problem was fixed.

Odor answered 13/2, 2018 at 19:20 Comment(0)
B
0

In my case, I found that I set the post method as private mistakenly. after changing private to public.

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

change to

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

Now works fine.

Bourbonism answered 11/7, 2019 at 5:47 Comment(0)
P
0

The cause isn't contrary to syntax rather than inappropriate usage of objects. Life Cycle of objects in ViewData, ViewBag, & View Life Cycle is shorter than in the session. Data defined in the formers will be lost after a request-response(if try to access after a request-response, you will get exceptions). So the formers are appropriate for passing data between View & Controller while the latter for storing temporary data. The temporary data should store in the session so that can be accessed many times.

Pretension answered 30/10, 2019 at 6:44 Comment(0)
A
-1

In my case there was a conflict in the namespaces , I have:

using System.Web.Mvc;

and

using System.Collections.Generic;

I explicitly want to use the Mvc one so I declared it as :

new System.Web.Mvc.SelectList(...)
Aeolian answered 10/3, 2015 at 15:55 Comment(1)
Unless my eyes deceive me, there is no SelectList in System.Collections.Generic.Danelaw

© 2022 - 2024 — McMap. All rights reserved.