You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在餐厅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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:52:50