ViewModel在asp.net mvc 5中发回一个null集合

时间:2015-04-12 14:45:53

标签: c# asp.net asp.net-mvc linq

    public class SaleItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class SalesDBContext
    {
        public static List<SaleItem> GetItems()
        {
            var items = new List<SaleItem>(){
                new SaleItem{Id=1,Name="Soap"},
                new SaleItem{Id=2,Name="Milk Power"},
                new SaleItem{Id=3,Name="Toothpaste"},
                new SaleItem{Id=4,Name="Ice Cream"}
            };
            return items.ToList();
        }
    }

    public class SalesViewModel
    {
        public string Item { get; set; }
        public List<SaleItem> itemlist { get; set; }
    }

我有以上SalesViewModel类和SalesDBContext用于虚拟数据生成。我想将项目添加到从下拉列表中选择的列表中。为此,我创建了以下视图:

@model MVCDropdown.Models.SalesViewModel
@using MVCDropdown.Models

<form method="post">
    <p>
        @Html.DropDownListFor(model => model.Item, new SelectList(ViewBag.Items, "Id", "Name"), "--select--")
        <input type="submit" value="Add" />
    </p>
    <p>
        @if (Model.itemlist != null)
        {
            <table>
                @foreach (var s in Model.itemlist)
                {
                    <tr>
                        <td>@s.Name</td>
                    </tr>
                }
            </table>
        }
    </p>
</form>

控制器

        [HttpGet]
        public ActionResult Index()
        {
            SalesViewModel model = new SalesViewModel
            { 
                Item = "",
                itemlist = new List<SaleItem>()
            };
            PopDrodown();
            return View(model);
        }

        [HttpPost]
        public ActionResult Index(SalesViewModel vm)
        {
            var t = SalesDBContext.GetItems().Where(x => x.Id == Convert.ToInt32(vm.Item)).FirstOrDefault();
            vm.itemlist.Add(t);
            PopDrodown();
            return View(vm);
        }

        private void PopDrodown()
        {
            ViewBag.Items = SalesDBContext.GetItems();
        }

添加到列表中的项目应显示在下拉列表下的表格中。但是,当我通过按下添加从后拉列表中发回选定项目时,它会向控制器返回空itemlist,之前添加的项目不存在。我该如何避免这个问题?

1 个答案:

答案 0 :(得分:3)

HTML表单中只有一个输入元素:即下拉列表。因此,提交表单时发送给控制器操作的唯一值是Item属性。如果要发送集合,可以使用隐藏字段:

<table>
    @for (var i = 0; i < Model.itemlist.Count; i++)
    {
        <tr>
            <td>
                @Html.HiddenFor(x => x.itemlist[i].Id)
                @Html.HiddenFor(x => x.itemlist[i].Name)
                @Html.DisplayFor(x => x.itemlist[i].Name)
            </td>
        </tr>
    }
</table>

显然,如果用户不应该编辑HTML表单中的值,那么更好的方法是使POST视图模型仅包含用户可以修改的属性,并且您将从中检索集合元素你在GET行动中检索它们的地方。