While binding dropdown in MVC, i get this error:
InvalidOperationException: There is no ViewData item of type
‘IEnumerable’ that has the key ‘marka’.
In another project this syntax works perfectly
There are a couple of posts about this on SO but none with an answer that seem to fix the problem in my current situation.
Model:
Product.cs:
public class Product
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "ProszÄ™ podac nazwÄ™ produktu")]
[Display(Name = "Nazwa produktu")]
[MaxLength(50, ErrorMessage = "Max 50 char")]
public string Name { get; set; }
[Display(Name = "Marka produktu")]
[Required]
[MaxLength(5, ErrorMessage = "Max 5 char")]
public string Brand { get; set; }
[Display(Name = "Cena produktu")]
[Required]
public int ProductPrice { get; set; }
[Display(Name = "Dział")]
[Required]
[MaxLength(1, ErrorMessage = "Max 1 char")]
public string Section { get; set; }
[Display(Name = "Materiał")]
[Required]
[MaxLength(5, ErrorMessage = "Max 5 char")]
public string Material { get; set; }
[Display(Name = "Typ")]
[Required]
[MaxLength(5, ErrorMessage = "Max 5 char")]
public string Type { get; set; }
}
Brand.cs:
public class Brand
{
[Key]
[Display(Name = "Identyfikator")]
[MaxLength(5, ErrorMessage = "Max 5 chars")]
public string Id { get; set; }
[Display(Name = "Nazwa")]
[MaxLength(50, ErrorMessage = "Max 50 chars")]
public string Name { get; set; }
}
View:
<div class="form-group">
<label asp-for="Brand" class="control-label"></label>
<div class="col-md-5">
@Html.DropDownList("marka", "Select brand")
</div>
<span asp-validation-for="Brand" class="text-danger"></span>
</div>
Controller:
// GET: Products/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var product = await _context.Product.FindAsync(id);
if (product == null)
{
return NotFound();
}
IEnumerable<SelectListItem> items = _context.Brand.Select(c => new SelectListItem
{
Value = c.Id,
Text = c.Name,
Selected = c.Id == product.Brand
}); ;
if (items != null)
{
ViewBag.marka = items;
}
return View(product);
}
// POST: Products/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Brand,ProductPrice,Section,Material,Type")] Product product)
{
if (id != product.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
string selBra = Request.Form["marka"].ToString();
product.Brand = selBra;
_context.Update(product);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(product.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(product);
}
>Solution :
fix the view I recommend you to use select instead of dropdown list, it automatically selects an item
<select class="form-control" asp-for="brand" asp-items="@ViewBag.marka"></select>
and fix the get action, by removing Selected and adding to List()
var items = _context.Brand.Select(c => new SelectListItem
{
Value = c.Id,
Text = c.Name
}).ToList();
fix the post action too , remove Bind,
public async Task<IActionResult> Edit(int id, Product product)
and remove from code
string selBra = Request.Form["marka"].ToString();
product.Brand = selBra;