MVC's Html.DropDownList and "There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key '...'

Posted by pjohnson on ASP.net Weblogs See other posts from ASP.net Weblogs or by pjohnson
Published on Fri, 26 Oct 2012 16:30:00 GMT Indexed on 2012/10/26 23:02 UTC
Read the original article Hit count: 569

Filed under:
|
|

ASP.NET MVC's HtmlHelper extension methods take out a lot of the HTML-by-hand drudgery to which MVC re-introduced us former WebForms programmers. Another thing to which MVC re-introduced us is poor documentation, after the excellent documentation for most of the rest of ASP.NET and the .NET Framework which I now realize I'd taken for granted.

I'd come to regard using HtmlHelper methods instead of writing HTML by hand as a best practice. When I upgraded a project from MVC 3 to MVC 4, several hidden fields with boolean values broke, because MVC 3 called ToString() on those values implicitly, and MVC 4 threw an exception until you called ToString() explicitly. Fields that used HtmlHelper weren't affected. I then went through dozens of views and manually replaced hidden inputs that had been coded by hand with Html.Hidden calls.

So for a dropdown list I was rendering on the initial page as empty, then populating via JavaScript after an AJAX call, I tried to use a HtmlHelper method:

@Html.DropDownList("myDropdown")

which threw an exception:

System.InvalidOperationException: There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'myDropdown'.

That's funny--I made no indication I wanted to use ViewData. Why was it looking there? Just render an empty select list for me. When I populated the list with items, it worked, but I didn't want to do that:

@Html.DropDownList("myDropdown", new List<SelectListItem>() { new SelectListItem() { Text = "", Value = "" } })

I removed this dummy item in JavaScript after the AJAX call, so this worked fine, but I shouldn't have to give it a list with a dummy item when what I really want is an empty select.

A bit of research with JetBrains dotPeek (helpfully recommended by Scott Hanselman) revealed the problem. Html.DropDownList requires some sort of data to render or it throws an error. The documentation hints at this but doesn't make it very clear. Behind the scenes, it checks if you've provided the DropDownList method any data. If you haven't, it looks in ViewData. If it's not there, you get the exception above.

In my case, the helper wasn't doing much for me anyway, so I reverted to writing the HTML by hand (I ain't scared), and amended my best practice: When an HTML control has an associated HtmlHelper method and you're populating that control with data on the initial view, use the HtmlHelper method instead of writing by hand.

© ASP.net Weblogs or respective owner

Related posts about .NET

Related posts about ASP.NET