Reputation: 10116
I've been trying to get DropDownListFor working in ASP.NET MVC using values from another table to link the model to the option selected. Full disclosure, I have very little idea what I'm doing and just working off examples.
Creating the DropDownList as follows:
@Html.DropDownListFor(model => model.GenreId, (SelectList)ViewBag.GenreSelect, new { @class = "form-control" })
GenreId is a column in the model's table.
I get the error:
An exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll but was not handled in user code
Additional information: There is no ViewData item of type 'IEnumerable' that has the key 'GenreId'
ViewBag set like this before going to the view: (Id and name are columns in the Genre table)
private void SetGenreViewBag(int? GenreId= null)
{
if (GenreId== null)
ViewBag.GenreSelect= new SelectList(db.Genres, "Id", "name");
else
ViewBag.GenreSelect = new SelectList(db.Genres, "Id", "name", GenreId);
}
The model has a column for the Id of the genre.
I think my main problem is I don't understand the syntax of the DropDownListFor function, plus there's a dozen different overloads for it so it's hard to decipher. What is the purpose of the first parameter with the lambda? It seems to be taking the value you specify from the select list values, but I don't get how this connects to the model. Haven't found a clear answer online.
I thought I had this working, but something I did made it stop working. I also had it working before that with DropDownList() but I saw that DropDownListFor would be a bit better plus I couldn't get the HTML attributes working properly in DropDownList().
Thank you!
EDIT: Inside controller:
public ActionResult Create()
{
SetGenreViewBag();
return View();
}
NOTE: The dropdown list shows all the right items (i.e. genres) but it crashes when I save the form.
// POST: Home/Create
[HttpPost]
public ActionResult Create(Song songToCreate)
{
try
{
db.Songs.Add(songToCreate);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Song model:
namespace MyModule.Models
{
using System;
using System.Collections.Generic;
public partial class Song
{
public int Id { get; set; }
public string name { get; set; }
public int genreId { get; set; }
}
}
Upvotes: 0
Views: 401
Reputation: 14614
When you have this syntax
@Html.DropDownListFor(model => model.GenreId, (SelectList)ViewBag.GenreSelect, new { @class = "form-control" })
The first parameter indicates which property of the model will be assigned the selected value of the dropdown, which is GenreId
in this case. I don't see anything wrong with the way you generate the dropdown, but since you get the error when you save the form, I think the problem is inside the Create
method with [HttpPost]
attribute below.
[HttpPost]
public ActionResult Create(Song songToCreate)
{
try
{
db.Songs.Add(songToCreate);
db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I would guess that an error happens for some reason inside the try
block, then the code in the catch
block is executed and it returns to the same page but ViewBag.GenreSelect
is already gone so you get the There is no ViewData item of type 'IEnumerable' that has the key 'GenreId'
error. Try to add SetGenreViewBag()
inside the catch
block so ViewBag.GenreSelect
will be repopulated. Also add (Exception ex)
to the catch
block to find out the error inside the try
block
[HttpPost]
public ActionResult Create(Song songToCreate)
{
try
{
db.Songs.Add(songToCreate);
db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex)
{
SetGenreViewBag();
return View();
}
}
Upvotes: 1