首页新闻找找看学习计划

asp.net mvc 在POST时,Controller如何获取IEnumerable的传值

0
悬赏园豆:40 [已解决问题] 解决于 2015-12-15 13:53

ViewModel:

    public class CreateCDViewModel
    {
        public CustomsDeclaration CustomsDeclaration { get; set; }
        public IEnumerable<PurchaseOrderDetail> PurchaseOrderDetail { get; set; }

        public CreateCDViewModel()
        {
            CustomsDeclaration = new CustomsDeclaration();
        }
    }

View绑定CreateCDViewModel,利用IEnumerable<PurchaseOrderDetail>显示表格:

订单号发票号供应商物料号数量金额
14/10/21-010-ZE-T   2300072371   HARTNGD 1159644-00 800.00 6700.55
14/10/21-010-ZE-T   2300072371   HARTNGD 1159649-00 300.00 3455.78
14/10/21-010-ZE-T   2300072371   HARTNGD 1159650-00 350.00 3500.00
14/10/21-011-ZE-T   2300072372   HARTNGD 1159644-00 200.00 2500.00
14/10/21-011-ZE-T   2300072372   HARTNGD 1159649-00 400.00 4305.00

页面提交POST,想把表格内容传回Controller的HTTP POST Action,Action同样传回的是ViewModel,但是IEnumerable<PurchaseOrderDetail>无法获取到任何值;

View 代码:

@model FreightOrderTraceability.ViewModels.CreateCDViewModel
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <input type="submit" value="创建" class="btn btn-default" />
    <table class="table table-striped table-bordered table-hover">
        <thead>
            <tr>
                @*<th></th>*@
                <th>订单号</th>
                <th>发票号</th>
                <th>供应商</th>
                <th>物料号</th>
                <th>数量</th>
                <th>金额</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.PurchaseOrderDetail)
            {
                @Html.HiddenFor(modelItem => item.Id)
                <tr>
                    @*<td class="text-center">@Html.CheckBoxFor(modelItem => item.IsSelected)</td>*@
                    <td>@Html.DisplayFor(modelItem => item.PurchaseOrder.OrderNum) &nbsp; @Html.HiddenFor(modelItem => item.PurchaseOrder.OrderNum)</td>
                    <td>@Html.DisplayFor(modelItem => item.PurchaseOrder.InvoiceNum) &nbsp; @Html.HiddenFor(modelItem => item.PurchaseOrder.InvoiceNum)</td>
                    <td>@Html.DisplayFor(modelItem => item.PurchaseOrder.Supplier)</td>
                    <td>@Html.DisplayFor(modelItem => item.PartNum)</td>
                    <td>@Html.DisplayFor(modelItem => item.Qty)</td>
                    <td>@Html.DisplayFor(modelItem => item.Amount)</td>
                </tr>
            }
        </tbody>
    </table>
}

Controller:

        public ActionResult Index()
        {
            CreateCDViewModel createCDViewModel = new CreateCDViewModel();
            createCDViewModel.PurchaseOrderDetail = db.PurchaseOrderDetails.Include(p => p.PurchaseOrder);
            return View(createCDViewModel);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(CreateCDViewModel createCDViewModel)
        {
            if (ModelState.IsValid)
            {
                TempData["QueryPOViewModel"] = createCDViewModel.PurchaseOrderDetail;
                return RedirectToAction("Create", "CustomsDeclarations");
            }
            return View(createCDViewModel);
        }

蓝色部分,传入页面的时候是有值的,黄色部分,POST传回时没有值。

请问:如何让控制器能绑定IEnumerable类型的模型?亦或者是IEnumerable是无法实现MVC绑定的,必须使用javascript返回JSON,然后在Controller接收?原生MVC无法实现获取表格内容吗?

夕阳寸草畔的主页 夕阳寸草畔 | 初学一级 | 园豆:48
提问于:2015-12-14 10:45
< >
分享
最佳答案
0

正好前两天碰到这个问题。http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

 

另外记得哦,@Html.DisplayFor,是无法post到服务器的。input才可以的。

收获园豆:40
写代码的小2B | 老鸟四级 |园豆:4346 | 2015-12-14 14:56

@Html.DisplayFor的值是不需要post的,主要是要传 @Html.HiddenFor(modelItem => item.Id) 的值post到Controller,这个文章我看了,IEnumerable和ICollection应该没大的区别,我也没看出和我写法的原理区别,也许是Razor的写法区别哪里有差错我没有对比出来;

夕阳寸草畔 | 园豆:48 (初学一级) | 2015-12-15 11:20

@夕阳寸草畔: 

数据POST到服务器端,获取数据是根据INPUT标签的Name,

<input type="hidden" name="PurchaseOrderDetail[0].Id" value="id" />

如果你获取的是集合的话,你页面输出的HTML应该是类似上面这样的。

这里需要注意下标是从0开始,并且不能中断。我看你页面上还有Checkbox,所以提交的数据下标有可能中断。

比如用户没有选择第一条数据,提交的数据下标就不是从0开始,那么PurchaseOrderDetail就获取不到值,根据你的需求建议你使用自定义下标,如下所示:

<input type="hidden" name="PurchaseOrderDetail.Index" value="0" />
    <input type="text" name="PurchaseOrderDetail[0].Id" value="id" />

 

加油。

写代码的小2B | 园豆:4346 (老鸟四级) | 2015-12-15 11:33

@写代码的小2B: 

我看了下网页源代码,name的值没有下标,某列的每行的name值都是一样的,但我并不知道用Razor语法的话,怎么用HtmlHelper来写出下标,我这个是系统自动生成的html标签。

        <tbody>
                <tr>
                    <td class="text-center"><input type="checkbox"></td>
                    <td><input data-val="true" data-val-number="字段 Id 必须是一个数字。" data-val-required="Id 字段是必需的。" id="item_Id" name="item.Id" type="hidden" value="8" /></td>
                    <td>14/10/21-010-ZE-T &nbsp; <input data-val="true" data-val-required="订单号 字段是必需的。" id="item_PurchaseOrder_OrderNum" name="item.PurchaseOrder.OrderNum" type="hidden" value="14/10/21-010-ZE-T" /></td>
                    <td>2300072371 &nbsp; <input data-val="true" data-val-required="发票号 字段是必需的。" id="item_PurchaseOrder_InvoiceNum" name="item.PurchaseOrder.InvoiceNum" type="hidden" value="2300072371" /></td>
                    <td>HARTING</td>
                    <td>1159644-00</td>
                    <td>800.00</td>
                    <td>6700.55</td>
                </tr>
                <tr>
                    <td class="text-center"><input type="checkbox"></td>
                    <td><input id="item_Id" name="item.Id" type="hidden" value="9" /></td>
                    <td>14/10/21-010-ZE-T &nbsp; <input id="item_PurchaseOrder_OrderNum" name="item.PurchaseOrder.OrderNum" type="hidden" value="14/10/21-010-ZE-T" /></td>
                    <td>2300072371 &nbsp; <input id="item_PurchaseOrder_InvoiceNum" name="item.PurchaseOrder.InvoiceNum" type="hidden" value="2300072371" /></td>
                    <td>HARTING</td>
                    <td>1159649-00</td>
                    <td>300.00</td>
                    <td>3455.78</td>
                </tr>
                <tr>
                    <td class="text-center"><input type="checkbox"></td>
                    <td><input id="item_Id" name="item.Id" type="hidden" value="11" /></td>
                    <td>14/10/21-010-ZE-T &nbsp; <input id="item_PurchaseOrder_OrderNum" name="item.PurchaseOrder.OrderNum" type="hidden" value="14/10/21-010-ZE-T" /></td>
                    <td>2300072371 &nbsp; <input id="item_PurchaseOrder_InvoiceNum" name="item.PurchaseOrder.InvoiceNum" type="hidden" value="2300072371" /></td>
                    <td>HARTING</td>
                    <td>1159650-00</td>
                    <td>350.00</td>
                    <td>3500.00</td>
                </tr>
                <tr>
                    <td class="text-center"><input type="checkbox"></td>
                    <td><input id="item_Id" name="item.Id" type="hidden" value="12" /></td>
                    <td>14/10/21-011-ZE-T  &nbsp; <input id="item_PurchaseOrder_OrderNum" name="item.PurchaseOrder.OrderNum" type="hidden" value="14/10/21-011-ZE-T " /></td>
                    <td>2300072372 &nbsp; <input id="item_PurchaseOrder_InvoiceNum" name="item.PurchaseOrder.InvoiceNum" type="hidden" value="2300072372" /></td>
                    <td>HARTING </td>
                    <td>1159644-00</td>
                    <td>200.00</td>
                    <td>2500.00</td>
                </tr>
                <tr>
                    <td class="text-center"><input type="checkbox"></td>
                    <td><input id="item_Id" name="item.Id" type="hidden" value="13" /></td>
                    <td>14/10/21-011-ZE-T  &nbsp; <input id="item_PurchaseOrder_OrderNum" name="item.PurchaseOrder.OrderNum" type="hidden" value="14/10/21-011-ZE-T " /></td>
                    <td>2300072372 &nbsp; <input id="item_PurchaseOrder_InvoiceNum" name="item.PurchaseOrder.InvoiceNum" type="hidden" value="2300072372" /></td>
                    <td>HARTING </td>
                    <td>1159649-00</td>
                    <td>400.00</td>
                    <td>4305.00</td>
                </tr>
        </tbody>
夕阳寸草畔 | 园豆:48 (初学一级) | 2015-12-15 12:27

@夕阳寸草畔: 

不一定要用这个@Html这种写法,直接输出INPUT就好。

写代码的小2B | 园豆:4346 (老鸟四级) | 2015-12-15 12:29

@写代码的小2B: 

不用@Html的话,请问如何绑定到@model上?

夕阳寸草畔 | 园豆:48 (初学一级) | 2015-12-15 13:12

@夕阳寸草畔: 

<input type="text" name="PurchaseOrderDetail[0].Id" value="@item.Id" />

直接这样输出就可以了。

给你看看我的例子

@foreach (var item in users.Where(m => m.OSType == type))
                                {
                                    <label class="checkbox-inline">
                                        <input type="hidden" name="Notices.Index" value="@item.Id" />
                                        <input type="checkbox" name="@String.Concat("Notices[",item.Id,"].AppUserName")" value="@item.AppUserName">@item.AppUserName
                                        <input type="checkbox" name="@String.Concat("Notices[",item.Id,"].OSType")" value="@item.OSType" style="display:none;" />
                                        <input type="checkbox" name="@String.Concat("Notices[",item.Id,"].AppUserAccount")" value="@item.AppUserAccount" style="display:none;" />
                                        <input type="checkbox" name="@String.Concat("Notices[",item.Id,"].iOSPushToken")" value="@item.iOSPushToken" style="display:none;" />
                                    </label>
                                }

和你的需求应该是一样的。

写代码的小2B | 园豆:4346 (老鸟四级) | 2015-12-15 13:17

@写代码的小2B: 

谢谢,通过拼接name属性得到传值,我刚开始搞错意思了,原来name=PurchaseOrderDetail[].Id的黄色部分必须和绑定的Model的名字PurchaseOrderDetail相同,我以为我用item,Razor会自动为我转换的。

不过我感觉这种写法有点歪门邪道的意思,不过问题是解决了,谢谢。

夕阳寸草畔 | 园豆:48 (初学一级) | 2015-12-15 13:53
其他回答(1)
0

实际上form是可以数组接的,只是很麻烦。很不好用。这种复杂情况还是用json传把。

吴瑞祥 | 园豆:28770 (高人七级) | 2015-12-14 11:33
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册