【问题标题】:ViewModel post back a null Collection in asp.net mvc 5ViewModel 在 asp.net mvc 5 中回发一个空集合
【发布时间】:2015-04-12 14:45:53
【问题描述】:
    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,并且以前添加的项目不存在。如何避免这个问题?

【问题讨论】:

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


    【解决方案1】:

    您的 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 操作中检索它们的位置相同。

    【讨论】:

    • 它给了我一个错误Object reference not set to an instance of an object.
    • 您是否保留了@if (Model.itemlist != null) 支票?您在哪条线上获得 NRE?
    • 不,它说错误在vm.itemlist.Add(t); 行中,我收到错误Object reference not set to an instance of an object.
    • 我忘记为 IdName 属性添加一个隐藏字段。确保您同时拥有它们,并且您使用了for 循环,如我的回答中所示,而不是foreach
    • 因为如果您使用foreach 循环,您将不会生成正确的隐藏字段的name 属性。您需要在标记中包含以下内容:&lt;input type="hidden" name="itemlist[0].Id" value="1" /&gt;, ... 我邀请您阅读以下博客文章:haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx 以更好地熟悉 ASP.NET MVC 模型绑定器期望传入数据的有线格式是为了补充你的视图模型的集合。
    猜你喜欢
    • 2016-02-13
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多