C# - MVC 4 多对多复选框值传递给另一个视图

C# - MVC 4 Many-To-Many Checkboxes values passed to another view

我一直在努力解决这个问题,并且已经搜索了几个小时,但仍然找不到解决方案。

我正在尝试从我的 AsoociateMenuItems 视图向我的索引视图显示选中的复选框的 ItemNames。我将不胜感激。

MenuItemViewModel:

public class MenuItemViewModel
{
    public int MenuId { get; set; }
    public double ItemPrice { get; set; }
    public string ItemName { get; set; }
    public bool Selected { get; set; }
    public virtual ICollection<IngredientViewModel> Ingredients { get; set;}
}

订单视图模型:

public class OrderViewModel
{
    public int OrderId { get; set; }
    public int TableNum { get; set; }
    public string Notes { get; set; }
    public double Discount { get; set; }
    public virtual ICollection<MenuItemViewModel> MenuItem { get; set; }
}

索引:

@model IEnumerable<Final_POS.Models.Order>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Employee.EmpName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.TableNum)
        </th>
        <th>
+
            @Html.DisplayNameFor(model => model.Discount)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Employee.EmpName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.TableNum)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Discount)
        </td>
        <td>
            @Html.EditorFor(modelItem => item.MenuItems)
        </td>
        <td>
            @Html.ActionLink("Edit", "AsoociateMenuItems", new { id=item.OrderId }) |
            @Html.ActionLink("Details", "Details", new { id=item.OrderId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.OrderId })
        </td>
    </tr>
}

</table>

关联菜单项: - 这是我的编辑视图的替代品

@model Final_POS.Models.ViewModel.OrderViewModel


@{
    ViewBag.Title = "AsoociateMenuItems";
}

<h2>AsoociateMenuItems</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>OrderViewModel</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.OrderId, new { htmlAttributes = new { @class = "form-control" } })

        <div class="form-group">
            @Html.LabelFor(model => model.TableNum, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.TableNum, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.TableNum, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.HiddenFor(model => model.Notes, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.HiddenFor(model => model.Notes, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Notes, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Discount, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Discount, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Discount, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.EmployeeEmpId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.EmployeeEmpId, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.EmployeeEmpId, "", new { @class = "text-danger" })
            </div>
        </div>

        @Html.EditorFor(model => model.MenuItem)
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

此行中的 AsoociateMenuItems 正在使用下一个代码片段@Html.EditorFor(model => model.MenuItem)

MenuItemViewModel:(视图)

@model Final_POS.Models.ViewModel.MenuItemViewModel

<fieldset>
    @Html.HiddenFor(model => model.MenuId)

    @Html.CheckBoxFor(model => model.Selected)
    @Html.DisplayFor(model => model.ItemName)
    @Html.DisplayFor(model => model.ItemPrice)

</fieldset>

控制器:

    public class OrdersController : Controller
    {
        private POSContext db = new POSContext();

        // GET: Orders
        public ActionResult Index()
        {
            var orders = db.Orders.Include(o => o.Employee);
            return View(orders.ToList());
        }

        // GET: Orders/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Order order = db.Orders.Find(id);
            if (order == null)
            {
                return HttpNotFound();
            }
            return View(order);
        }

        // GET: Orders/Create
        public ActionResult Create()
        {
            ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName");
            return View();
        }

        // POST: Orders/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "OrderId,TableNum,Discount,EmployeeEmpId")] Order order)
        {
            if (ModelState.IsValid)
            {
                db.Orders.Add(order);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName", order.EmployeeEmpId);
            return View(order);
        }

        // GET: Orders/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Order order = db.Orders.Find(id);
            if (order == null)
            {
                return HttpNotFound();
            }
            ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName", order.EmployeeEmpId);
            return View(order);
        }

        // POST: Orders/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "OrderId,TableNum,Discount,EmployeeEmpId")] Order order)
        {
            if (ModelState.IsValid)
            {
                db.Entry(order).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName", order.EmployeeEmpId);
            return View(order);
        }

        // GET: Orders/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Order order = db.Orders.Find(id);
            if (order == null)
            {
                return HttpNotFound();
            }
            return View(order);
        }

        // POST: Orders/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Order order = db.Orders.Find(id);
            db.Orders.Remove(order);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        public ActionResult AsoociateMenuItems(int? id)
        {
            Order _order = db.Orders.Find(id);

            if (_order == null)
            {
                return HttpNotFound();
            }

            OrderViewModel _orderViewModel = new OrderViewModel()
            {
                OrderId = _order.OrderId,
                Discount = _order.Discount,
                TableNum = _order.TableNum,
                EmployeeEmpId = _order.EmployeeEmpId
            };

            List<MenuItemViewModel> _menuItemViewModel = new List<MenuItemViewModel>();
            foreach (MenuItem menuItem in db.MenuItems)
            {
                _menuItemViewModel.Add(new MenuItemViewModel()
                {
                    MenuId = menuItem.MenuId,
                    ItemName = menuItem.ItemName,
                    ItemPrice = menuItem.ItemPrice,
                    Selected = _order.MenuItems.Contains(menuItem)
                });
            }

            _orderViewModel.MenuItem = _menuItemViewModel;

            return View(_orderViewModel);
        }



        [HttpPost]
        public ActionResult AsoociateMenuItems(OrderViewModel _orderViewModel)
        {
            Order _order = db.Orders.Find(_orderViewModel.OrderId);
            _order.MenuItems.Clear();

            foreach (MenuItemViewModel _menuItemViewModel in _orderViewModel.MenuItem)
            {
                if (_menuItemViewModel.Selected)
                {
                    MenuItem _menuItem = db.MenuItems.Find(_menuItemViewModel.MenuId);
                    _order.MenuItems.Add(_menuItem);
                }
            }
            db.SaveChanges();

            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

让我们开始吧。 你的问题真的很难理解。但我希望我能理解。 首先,您应该在所有视图中使用模型。这真的很重要。你必须做。最简单的方法 - 只需使用 EmpName

扩展 OrderViewModel
public class OrderViewModel
{
    public int OrderId { get; set; }
    public int TableNum { get; set; }
    public string Notes { get; set; }
    public double Discount { get; set; }
    public string EmpName { get; set; }
    public virtual ICollection<MenuItemViewModel> MenuItems { get; set; }  //renamed to plural  
}

比改变你的Index视图

@model IEnumerable<OrderViewModel>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.EmpName) 
        </th>
        <th>
            @Html.DisplayNameFor(model => model.TableNum)
        </th>
        <th>

            @Html.DisplayNameFor(model => model.Discount)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.EmpName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.TableNum)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Discount)
        </td>
        <td>
            @Html.EditorFor(modelItem => item.MenuItems)
        </td>
        <td>
            @Html.ActionLink("Edit", "AsoociateMenuItems", new { id=item.OrderId }) |
            @Html.ActionLink("Details", "Details", new { id=item.OrderId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.OrderId })
        </td>
    </tr>
}

</table>

比更改控制器方法Index(也只需从数据库中获取菜单项)

    // GET: Orders
    public ActionResult Index()
    {
        var orders = db.Orders.Include(o => o.Employee).Include(o => o.MenuItems);
        var orderModels = new List<OrderViewModel>();
        foreach(var _order in orders)
        {
            OrderViewModel _orderViewModel = new OrderViewModel()
            {
                OrderId = _order.OrderId,
                Discount = _order.Discount,
                TableNum = _order.TableNum,
                EmpName = _order.Employee.EmpName
            };

            List<MenuItemViewModel> _menuItemViewModels = new List<MenuItemViewModel>();
            foreach (MenuItem menuItem in order.MenuItems)
            {
                if(_order.MenuItems.Contains(menuItem)) //where selected is true
                {
                    _menuItemViewModel.Add(new MenuItemViewModel()
                    {
                        MenuId = menuItem.MenuId,
                        ItemName = menuItem.ItemName,
                        ItemPrice = menuItem.ItemPrice,
                    });
                }
            }
            _orderViewModel.MenuItems = _menuItemViewModels;
            orderModels.Add(_orderViewModel);
        }
        return View(orderModels);
    } 

希望你能明白我的意思。当然,我的代码需要代码重构,但你可以自己做。