0

How to fix this error? And why it's happening?

here is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'IngredientTypeID'.

Controller:

public ActionResult AddIngridient(int id = 0)
{
    IEnumerable<Ingredient> ListOfIngridient =  FRE.Ingredient.Select(key => key).ToList();
    ViewBag.IngridientsList = new SelectList(ListOfIngridient,"IngredientID", "IngredientName");

    IEnumerable<Amount> ListOfAmounts = FRE.Amount.Select(key => key).ToList();
    ViewBag.AmountsList = new SelectList(ListOfAmounts, "AmountID", "AmountName");

    return View(new Ingredients { IngredientID = id });
}

[HttpPost]
public ActionResult AddIngridient(Ingredients ingridients)
{
    FRE.Ingredients.Add(ingridients);
    FRE.SaveChanges();
    return View();
}

View:

@model FoodRecipes.Models.Ingredients
@{
    ViewBag.Title = "AddIngridient";
}

<h2>AddIngridient</h2>

@using (Html.BeginForm("AddIngridient", "Home"))
{
    @Html.HiddenFor(x => x.IngredientID) 
    @Html.DropDownListFor(model => model.IngredientTypeID, (SelectList)ViewBag.IngridientsList)
    <br />
    @Html.DropDownListFor(model => model.AmountID, (SelectList)ViewBag.AmountsList)
    <input type="submit" value="Create" />
}

Model:

public partial class Ingredients
{
    public int IngredientID { get; set; }
    public Nullable<int> AmountID { get; set; }
    public Nullable<int> IngredientTypeID { get; set; }
}

enter image description here

A191919
  • 3,422
  • 7
  • 49
  • 93

2 Answers2

2

Without much information I suspect the error happens after you submit. It happens because you are using the same view in your POST action as in your GET action, but not passing any data. You get the error since the view is trying to render the HTML expecting the model to be a valid object.

Try using a different view in your POST action, like this:

return View("Added");

Create a view with that name which does not have a model and that part should work.


NOTE: Best practice would be to create a view-model that contains all data you need (IngredientsList, AmountsList), so you don't have to use ViewBag for anything. Something like:

public class IngredientViewModel
{
    public Ingredient Ingredient { get; set; }
    public IEnumerable<Ingredient> IngredientsList { get; set; }
    public IEnumerable<Amount> AmountsList { get; set; }
}

Use this class as your model. Btw, (I'm assuming it's a typo in your question) make sure you are using consistent pluralization for your class names. Either Ingredient or Ingredients.

Floremin
  • 3,969
  • 15
  • 20
1

The error is thrown because you are only setting ViewBag.IngridientsList and ViewBag.AmountsList in the Get action and not the Post action. If you are going to use ViewBag to pass in DropDownList items, you need to make sure you set them every time you load the view.

public ActionResult AddIngridient(int id = 0)
{
    LoadViewBag();
    return View(new Ingredients { IngredientID = id });
}

[HttpPost]
public ActionResult AddIngridient(Ingredients ingridients)
{
    if (ModelState.IsValid)
    {
        FRE.Ingredients.Add(ingridients);
        FRE.SaveChanges();
        return RedirectToAction("Index");
    }
    LoadViewBag();
    return View(ingridients);
}

private void LoadViewBag()
{
    IEnumerable<Ingredient> ListOfIngridient = FRE.Ingredient.Select(key => key).ToList();
    ViewBag.IngridientsList = new SelectList(ListOfIngridient, "IngredientID", "IngredientName");

    IEnumerable<Amount> ListOfAmounts = FRE.Amount.Select(key => key).ToList();
    ViewBag.AmountsList = new SelectList(ListOfAmounts, "AmountID", "AmountName");
}
JamieD77
  • 13,796
  • 1
  • 17
  • 27