首页 > 解决方案 > 如何将 IEnumarable 从视图发送回控制器

问题描述

我对 MVC 和 ASP.Net 很陌生,我的控制器有 2 个用于 GET 和 POST 的创建方法。通过 Get 方法,我正在生成一个列表并将其发送到视图中。在视图上,我正在更改列表中每个 var 中的特定值,并尝试将其发送回控制器和 POST 方法。到达 Post 方法时,列表的值为空。我发送的列表是产品列表,我正在使用 ViewModel 创建一个具有公共值的类以传递给视图。

要传递由视图编辑的 IEnumarable 集合,我尝试使用 BeginCollectionForm,通过 ViewBag 设置项目,更改模型(@model IEnumerable),但每次按下 Checkout 按钮时,Post 方法中的列表仍然是无效的。

经过大量尝试和更改,目前我的代码如下所示: OrderController.cs (Relevant Parts)

public class OrderController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();
        public ActionResult Create()
        {
            var meals = (from m in db.meals
                         select new ItemVM
                         {
                             Id = m.Id,
                             Name = m.Name,
                             Price = m.Price,
                             ItemType = "Meal",
                             ImageURL = m.ImageUrl,
                             Quantity = 0
                         }).ToList();
            var drinks = (from d in db.drinks
                          select new ItemVM
                          {
                              Id = d.Id,
                              Name = d.Name,
                              Price = d.Price,
                              ItemType = "Drink",
                              Quantity = 0
                          }).ToList();
            //More Like That....
            List<ItemVM> items = new List<ItemVM>();
            items.AddRange(meals);
            items.AddRange(drinks);//More Like...
            return View(items.ToList());
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(IEnumerable<ItemVM> items = null)
        {
            //Here items equals to null.
            if (ModelState.IsValid) 
            {
               //.....
            }
            return View();
        }

视图/订单/Create.cshtml:

@model IEnumerable<***.ViewModel.ItemVM>

@{
    ViewBag.Title = "Create";
    var lst = Model.ToList();
    ViewBag.List = Model.ToList();
}
<style>
    tr td {
        vertical-align: middle;
    }
</style>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <h3> Order:</h3>
    <table class="table table-condensed table-hover">
        <tr calss="table-header">
            <th>
                @Html.DisplayName("Preview")
            </th>
            <th>
                @Html.DisplayNameFor(m => m.Name)
            </th>
            <th>
                @Html.DisplayNameFor(m => m.Price)
            </th>
            <th>
                @Html.DisplayName("Quantity")
            </th>
            <th></th>
            <th></th>
        </tr>
        @for (var i = 0; i < Model.Count(); i++)
        {
            <tr>
                <td>
                    @if (Model.ElementAt(i).ImageURL != null)
                    {
                        <img src="@Url.Content(Model.ElementAt(i).ImageURL)" alt="IMAGES" height="100" width="100" />
                    }
                </td>
                <td>
                    @Html.DisplayFor(m => Model.ElementAt(i).Name)
                </td>
                <td>
                    @Html.DisplayFor(m => Model.ElementAt(i).Price)
                </td>
                <td>
                    <a type="button" class="btn btn-danger btn-xs" href="#">
                        <span class="glyphicon glyphicon-minus"></span>
                    </a>
                    @Html.EditorFor(l => lst[i].Quantity, new { htmlattribute = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => lst[i].Quantity, "", new { @class = "text-danger" })
                    <a type="button" class="btn btn-success btn-xs" id="plus" href="#">
                        <span class="glyphicon glyphicon-plus"></span>
                    </a>
                </td>
            </tr>
        }
    </table>
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Checkout" class="btn btn-primary"/>
    </div>
</div>
}

ViewModel/ItemVM.cs:

namespace ***.ViewModel
{
    public class ItemVM
    {
        [Required]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        [DataType(DataType.Currency)]
        public double Price { get; set; }
        [Required]
        public string ItemType { get; set; }

        public string ImageURL { get; set; }
        [Required]
        public int Quantity { get; set; }
    }
}

最后,我想使用“创建”(HttpPost 方法)根据从视图接收到的列表中的值创建新订单。这样做并将 IEnumarable 接收到 POST 方法的正确方法是什么?

标签: c#.netasp.net-mvc-5controllerhttp-post

解决方案


好的,我终于能够让它工作了。我已将 更改@model为 List 类型,将其添加(actionName, Controller, FormMethod)到 HTML Helper Html.BeginFormModel[i]在循环内用于访问变量并将所有未更改的变量标记为 @Html.HiddenFor.

创建.cshtml:

@model List<MarsBurgerV1.ViewModel.ItemVM>
@{
    ViewBag.Title = "Create";
}
@using (Html.BeginForm("Create","Order", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    <h3> Order:</h3>
    <table class="table table-condensed table-hover">
        <tr calss="table-header">
            <th>
                @Html.DisplayName("Preview")
            </th>
            <th>
                @Html.DisplayName("Name")
            </th>
            <th>
                @Html.DisplayName("Price")
            </th>
            <th>
                @Html.DisplayName("Quantity")
            </th>
            <th></th>
            <th></th>
        </tr>
        @for (var i = 0; i < Model.Count(); i++)
        {
        <tr>
            @Html.HiddenFor(m => Model[i].Id)
            @Html.HiddenFor(m => Model[i].Type)
            <td>
                @Html.HiddenFor(m => Model[i].ImageURL)
                @if (Model[i].ImageURL != null)
                {
                    <img src="@Url.Content(Model[i].ImageURL)" alt="IMAGES" height="100" width="100" />
                }
                @Html.ValidationMessageFor(model => Model[i].ImageURL, "", new { @class = "label-control" })
            </td>
            <td>
                @Html.HiddenFor(m => Model[i].Name)
                @Html.DisplayFor(m => Model[i].Name)
                @Html.ValidationMessageFor(model => Model[i].Name, "", new { @class = "label-control" })
            </td>
            <td>
                @Html.HiddenFor(m => Model[i].Price)
                @Html.DisplayFor(m => Model[i].Price, new { @class = "form-control" })
                @Html.ValidationMessageFor(model => Model[i].Price, "", new { @class = "label-control" })
            </td>
            <td>
                <a type="button" class="btn btn-danger btn-xs" href="#">
                    <span class="glyphicon glyphicon-minus"></span>
                </a>
                @Html.EditorFor(model => Model[i].Quantity, new { htmlattribute = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => Model[i].Quantity, "", new { @class = "text-danger" })
                <a type="button" class="btn btn-success btn-xs" id="plus" href="#">
                    <span class="glyphicon glyphicon-plus"></span>
                </a>
            </td>
        </tr>
        }
    </table>
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <button type="submit" value="Checkout" class="btn btn-primary"/>
    </div>
</div>
}

谢谢大家的帮助。


推荐阅读