I'm attempting to retrieve my recipes and ingredients from my recipe-Ingredient create view, but f data are not being transferred via view-Bag. Here is my code. What am I doing wrong? Or am I using the wrong approach? How do I create a recipe-Ingredient. Here are my codes:
public class Recipe
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
[ValidateNever]
public ICollection<RecipeIngredient> RecipeIngredient { get;}
}
public class Ingredient
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int UnitOfMeasureId { get; set; }
public UnitOfMeasure UnitOfMeasure { get; set; }
public int QuantityOfMeasureId { get; set; }
public QuantityOfMeasure QuantityOfMeasure { get; set; }
}
public class RecipeIngredient
{
public int Id { get; set; }
public int IngredientId { get; set; }
public Ingredient Ingredient { get; set; }
public int RecipeId { get; set; }
public Recipe Recipe { get; set; }
}
Controller
public class RecipeIngredientController : Controller
{
private readonly ApplicationContext _context;
public RecipeIngredientController(ApplicationContext context)
{
_context = context;
}
public IActionResult Index()
{
IEnumerable<RecipeIngredient> listOfrecipeIngredient = _context.RecipeIngredients;
return View(listOfrecipeIngredient);
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(RecipeIngredient recipeIngredient)
{
IEnumerable<SelectListItem> listRecipes = _context.Recipes.Select(u => new SelectListItem { Text = u.Name, Value = u.Id.ToString() });
IEnumerable<SelectListItem> listIngredients =_context.Ingredients.Select(u=> new SelectListItem { Text = u.Name, Value =u.Id.ToString() });
if(ModelState.IsValid)
{
ViewBag.listRecipes = listRecipes;
ViewBag.listIngredients =listIngredients;
_context.RecipeIngredients.Add(recipeIngredient);
_context.SaveChanges();
}
return RedirectToAction("Index");
}
}
It shows the dropdown, but there is nothing inside; it's empty, with no data to choose from.
I tried using viewBag to pass data from the controller to the view.
Maybe I'm doing it wrong. Any suggestion?
What am I doing wrong? Or am I using the wrong approach? How do I create a recipe-Ingredient.
Absolutely, you are getting the expected result as you are doing incorrect way. You should move your ViewBag.listRecipes
and ViewBag.listIngredients
inside your Create [HttpGet] method if you would like to load your dropdown while the page load. As its inside your [HttpPost] Create method, consequently you are not getting any value into it because it has not called yet.
It shows the dropdown, but there is nothing inside; it's empty, with no data to choose from. I tried using viewBag to pass data from the controller to the view.
To populate your dropdown value within create [HttpGet] you have to move your following two dropdown from create [HttpPost] to create [HttpGet]:
IEnumerable<SelectListItem> listRecipes = _context.Recipes.Select(u => new SelectListItem { Text = u.Name, Value = u.Id.ToString() });
IEnumerable<SelectListItem> listIngredients =_context.Ingredients.Select(u=> new SelectListItem { Text = u.Name, Value =u.Id.ToString() });
Correct way:
[HttpGet]
public IActionResult Create()
{
IEnumerable<SelectListItem> listRecipes = _context.Recipes.Select(u => new SelectListItem { Text = u.Name, Value = u.Id.ToString() });
IEnumerable<SelectListItem> listIngredients =_context.Ingredients.Select(u=> new SelectListItem { Text = u.Name, Value =u.Id.ToString() });
ViewBag.listRecipes = listRecipes;
ViewBag.listIngredients =listIngredients;
return View();
}
Complele Demo:
You can do as followiwng:
Controller:
[HttpGet]
public IActionResult Create()
{
List<SelectListItem> ingredientList = new List<SelectListItem>();
ingredientList.Add(new SelectListItem { Text = "Ingredient-A", Value = "Ingredient-A" });
ingredientList.Add(new SelectListItem { Text = "Ingredient-B", Value = "Ingredient-B" });
ingredientList.Add(new SelectListItem { Text = "Ingredient-C", Value = "Ingredient-C" });
ViewBag.listIngredients = ingredientList;
return View();
}
Note: I am creating a conceeptual list to show you where to define the dropdown list if you want to visualize that when the create page loads.
View:
@model DotNet6MVCWebApp.Models.Ingredient
<form asp-action="Create">
<div>
@Html.DropDownList("Id",(IEnumerable<SelectListItem>)ViewBag.listIngredients , "Select Ingredients")
@Html.ValidationMessageFor(model => model.Id)
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
Output:
Note: In addition to above examplee, I would like to inform you that you could implement dropdown by using Select Tag Helper which is recommended more robust and less problematic check our official document here for more details.