How do I ModelBind a many-to-many relationship with MVC 3 and Entity Framework Code First?

前端 未结 3 1824
执念已碎
执念已碎 2021-01-06 13:46

I\'m coming across the same problem in my MVC 3 applications. I\'ve got a view to create an new product and that product can be assigned to one or more categories. Here are

3条回答
  •  长情又很酷
    2021-01-06 14:33

    What you could try is the following: Bind to your ViewModel instead of Product in your post action:

    [HttpPost]
    public ActionResult Create(ProductEditViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            foreach (var value in viewModel.CategorySelections
                                           .Where(c => c.Selected)
                                           .Select(c => c.Value))
            {
                // Attach "stub" entity only with key to make EF aware that the
                // category already exists in the DB to avoid creating a new category
                var category = new Category { CategoryID = int.Parse(value) };
                db.Categories.Attach(category);
    
                viewModel.Product.Categories.Add(category);
            }
            db.Products.Add(viewModel.Product);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    
        return View(new ProductEditViewModel(
            viewModel.Product, db.Categories.ToList()));
    }
    

    I am not sure though if this is the "standard way".

    Edit

    The return case when the model is invalid cannot work in my example above because viewModel.Product.Categories collection is empty, so you would get no selected category item in the view and not the items which the user had selected before.

    I don't know how exactly you bind the collection to the view (your "list of checkboxes"?) but when using a ListBox which allows multiple selection then there seems to be a solution along the lines of this answer: Challenges with selecting values in ListBoxFor. I just had asked Darin in the comments if the list of selected item ids also will get bound to the ViewModel in an post action and he confirmed that.

提交回复
热议问题