如何在餐厅CRUD项目的菜单页面添加酱料复选框?
解决菜单添加页面酱料复选框不显示问题
问题根源
你的代码无法生效主要有几个核心原因:
AddMenuViewModel未包含视图中用到的Count、Id、IsSelected、Name属性,视图无法正确绑定数据- 控制器的GET请求方法没有加载所有已添加的酱料数据并传递给视图
- 视图中循环遍历的对象结构与ViewModel不匹配
解决方案步骤
1. 重构AddMenuViewModel
创建包含菜单基础信息和酱料选择列表的ViewModel,确保属性与视图需求匹配:
namespace MVC_Hamburger_Project.Models { public class AddMenuViewModel { // 菜单基础属性 public string MenuName { get; set; } public string MenuDescription { get; set; } public double MenupPrice { get; set; } public double NumberOfMenu { get; set; } // 酱料选择列表 public List<SauceSelectionViewModel> SauceSelections { get; set; } = new List<SauceSelectionViewModel>(); } // 单个酱料选择项的ViewModel public class SauceSelectionViewModel { public Guid Id { get; set; } public string Name { get; set; } public bool IsSelected { get; set; } } }
2. 修改控制器的GET请求方法
在菜单控制器的Add方法中,加载所有已存在的酱料并映射到ViewModel的酱料列表:
public IActionResult Add() { // 从数据库获取所有酱料 var allSauces = _context.ExtraSauces.ToList(); // 映射到ViewModel var viewModel = new AddMenuViewModel { SauceSelections = allSauces.Select(s => new SauceSelectionViewModel { Id = s.Id, Name = s.SauceName }).ToList() }; return View(viewModel); }
3. 修正视图代码
更新视图,绑定正确的ViewModel属性,遍历SauceSelections列表渲染复选框:
@model MVC_Hamburger_Project.Models.AddMenuViewModel @{ ViewData["Title"] = "Add"; } <h1>Add Menu</h1> <div class="row"> <div class="col-md-4"> <form asp-action="Add"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="MenuName" class="control-label">Menu Name</label> <input asp-for="MenuName" class="form-control" /> <span asp-validation-for="MenuName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="MenuDescription" class="control-label">Menu Description</label> <input asp-for="MenuDescription" class="form-control" /> <span asp-validation-for="MenuDescription" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="MenupPrice" class="control-label">Menu Price</label> <input asp-for="MenupPrice" class="form-control" /> <span asp-validation-for="MenupPrice" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="NumberOfMenu" class="control-label">Number of Menu</label> <input asp-for="NumberOfMenu" class="form-control" /> <span asp-validation-for="NumberOfMenu" class="text-danger"></span> </div> <div class="form-group mt-3"> <label class="control-label">Available Sauces</label> <table class="table mt-2"> @for (int i = 0; i < Model.SauceSelections.Count; i++) { <tr> <td> @Html.HiddenFor(model => model.SauceSelections[i].Id) @Html.CheckBoxFor(model => model.SauceSelections[i].IsSelected) </td> <td> @Model.SauceSelections[i].Name </td> </tr> } </table> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div> <div> <a asp-action="Index">Back to List</a> </div> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }
4. 处理POST请求保存菜单与酱料关联
在控制器的POST Add方法中,创建菜单并关联选中的酱料:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult Add(AddMenuViewModel viewModel) { if (ModelState.IsValid) { // 创建菜单实体 var menu = new Menu { MenuId = Guid.NewGuid(), MenuName = viewModel.MenuName, MenuDescription = viewModel.MenuDescription, MenupPrice = viewModel.MenupPrice, NumberOfMenu = viewModel.NumberOfMenu, extraSauces = new List<ExtraSauce>() }; // 添加选中的酱料关联 var selectedSauceIds = viewModel.SauceSelections .Where(s => s.IsSelected) .Select(s => s.Id) .ToList(); var selectedSauces = _context.ExtraSauces.Where(s => selectedSauceIds.Contains(s.Id)).ToList(); foreach (var sauce in selectedSauces) { sauce.MenuId = menu.MenuId; menu.extraSauces.Add(sauce); } _context.Menus.Add(menu); _context.SaveChanges(); return RedirectToAction(nameof(Index)); } // 如果验证失败,重新加载酱料列表并保留选中状态 viewModel.SauceSelections = _context.ExtraSauces.Select(s => new SauceSelectionViewModel { Id = s.Id, Name = s.SauceName, IsSelected = viewModel.SauceSelections?.FirstOrDefault(ss => ss.Id == s.Id)?.IsSelected ?? false }).ToList(); return View(viewModel); }
额外注意点
确保DbContext中正确配置Menu与ExtraSauce的一对多关系:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ExtraSauce>() .HasOne(e => e.Menu) .WithMany(m => m.extraSauces) .HasForeignKey(e => e.MenuId) .OnDelete(DeleteBehavior.SetNull); }
内容的提问来源于stack exchange,提问作者user22624857
相关产品推荐
相关产品推荐

