Home > OS >  InvalidOperationException: There is no ViewData item of type 'IEnumerable<SelectListItem>
InvalidOperationException: There is no ViewData item of type 'IEnumerable<SelectListItem>

Time:01-27

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 >
   <label asp-for="Brand" ></label>
   <div >
      @Html.DropDownList("marka", "Select brand")
   </div>
   <span asp-validation-for="Brand" ></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);
    }

CodePudding user response:

fix the view I recommend you to use select instead of dropdown list, it automatically selects an item

 <select   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;
  •  Tags:  
  • Related