张贴表单数组,但不成功

我正在用C#和.NET Framework 4.5.1开发ASP.NET MVC 5网站。

我在cshtml文件中有这个form

 @model MyProduct.Web.API.Models.ConnectBatchProductViewModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Create</title> </head> <body> @if (@Model != null) { <h4>Producto: @Model.Product.ProductCode, Cantidad: @Model.ExternalCodesForThisProduct</h4> using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post)) { @Html.HiddenFor(model => model.Product.Id, new { @id = "productId", @Name = "productId" }); <div> <table id ="batchTable" class="order-list"> <thead> <tr> <td>Cantidad</td> <td>Lote</td> </tr> </thead> <tbody> <tr> <td>@Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].Quantity")</td> <td>@Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].BatchName")</td> <td><a class="deleteRow"></a></td> </tr> </tbody> <tfoot> <tr> <td colspan="5" style="text-align: left;"> <input type="button" id="addrow" value="Add Row" /> </td> </tr> </tfoot> </table> </div> <p><input type="submit" value="Seleccionar" /></p> } } else { <div>Error.</div> } <script src="~/Scripts/jquery-2.1.3.min.js"></script> <script src="~/js/createBatches.js"></script> <!-- Resource jQuery --> </body> </html> 

这是行动方法:

 [HttpPost] public ActionResult Save(FormCollection form) { return null; } 

而这两个ViewModel

 public class BatchProductViewModel { public int Quantity { get; set; } public string BatchName { get; set; } } public class ConnectBatchProductViewModel { public Models.Products Product { get; set; } public int ExternalCodesForThisProduct { get; set; } public IEnumerable<BatchProductViewModel> BatchProducts { get; set; } } 

但我在FormCollection form var: 在这里输入图像描述

但我想要一个IEnumerable<BatchProductViewModel> model

 public ActionResult Save(int productId, IEnumerable<BatchProductViewModel> model); 

如果我使用上面的方法签名,这两个参数都是空的。

我想要一个IEnumerable因为用户将使用jQuerydynamic地添加更多的行。

这是jQuery脚本:

 jQuery(document).ready(function ($) { var counter = 0; $("#addrow").on("click", function () { counter = $('#batchTable tr').length - 2; var newRow = $("<tr>"); var cols = ""; var quantity = 'ConnectBatchProductViewModel.BatchProducts[0].Quantity'.replace(/\[.{1}\]/, '[' + counter + ']'); var batchName = 'ConnectBatchProductViewModel.BatchProducts[0].BatchName'.replace(/\[.{1}\]/, '[' + counter + ']'); cols += '<td><input type="text" name="' + quantity + '"/></td>'; cols += '<td><input type="text" name="' + batchName + '"/></td>'; cols += '<td><input type="button" class="ibtnDel" value="Delete"></td>'; newRow.append(cols); $("table.order-list").append(newRow); counter++; }); $("table.order-list").on("click", ".ibtnDel", function (event) { $(this).closest("tr").remove(); counter -= 1 $('#addrow').attr('disabled', false).prop('value', "Add Row"); }); }); 

任何想法?

我已经检查过这个答案 , 这篇文章,但我没有得到我的代码工作。

您需要在for循环中为集合生成控件,以便使用索引器正确命名它们(请注意,属性BatchProducts需要是IList<BatchProductViewModel>

 @using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post)) { .... <table> .... @for(int i = 0; i < Model.BatchProducts.Count; i++) { <tr> <td>@Html.TextBoxFor(m => m.BatchProducts[i].Quantity)</td> <td>@Html.TextBoxFor(m => m.BatchProducts[i].BatchName)</td> <td> // add the following to allow for dynamically deleting items in the view <input type="hidden" name="BatchProducts.Index" value="@i" /> <a class="deleteRow"></a> </td> </tr> } .... </table> .... } 

然后POST方法需要

 public ActionResult Save(ConnectBatchProductViewModel model) { .... } 

编辑

注意:除了编辑之外,如果您想在视图中dynamic添加和删除BatchProductViewModel项目,则需要使用此答案中讨论的BeginCollectionItem助手或html模板

dynamic添加新项目的模板将是

 <div id="NewBatchProduct" style="display:none"> <tr> <td><input type="text" name="BatchProducts[#].Quantity" value /></td> <td><input type="text" name="BatchProducts[#].BatchName" value /></td> <td> <input type="hidden" name="BatchProducts.Index" value ="%"/> <a class="deleteRow"></a> </td> </tr> </div> 

请注意,虚拟索引器和隐藏input的不匹配值会阻止此模板回发。

然后脚本添加一个新的BatchProducts将是

 $("#addrow").click(function() { var index = (new Date()).getTime(); // unique indexer var clone = $('#NewBatchProduct').clone(); // clone the BatchProducts item // Update the index of the clone clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']')); clone.html($(clone).html().replace(/"%"/g, '"' + index + '"')); $("table.order-list").append(clone.html()); }); 

在您的后期Methode您收到“MyProduct.Web.API.Models.ConnectBatchProductViewModel”作为参数。
使用Post方法的现有模型。

为什么你想从你的模型IEnumerable? 模型中只有一个可用的id。

您可以通过video教程访问这篇文章,获取完整的源代码。

你必须首先创build一个动作,从那里我们可以传递对象列表

 [HttpGet] public ActionResult Index() { List<Contact> model = new List<Contact>(); using (MyDatabaseEntities dc = new MyDatabaseEntities()) { model = dc.Contacts.ToList(); } return View(model); } 

那么我们需要为这个行为创build一个视图

 @model List<UpdateMultiRecord.Contact> @{ ViewBag.Title = "Update multiple row at once Using MVC 4 and EF "; } @using (@Html.BeginForm("Index","Home", FormMethod.Post)) { <table> <tr> <th></th> <th>Contact Person</th> <th>Contact No</th> <th>Email ID</th> </tr> @for (int i = 0; i < Model.Count; i++) { <tr> <td> @Html.HiddenFor(model => model[i].ContactID)</td> <td>@Html.EditorFor(model => model[i].ContactPerson)</td> <td>@Html.EditorFor(model => model[i].Contactno)</td> <td>@Html.EditorFor(model => model[i].EmailID)</td> </tr> } </table> <p><input type="submit" value="Save" /></p> <p style="color:green; font-size:12px;"> @ViewBag.Message </p> } @section Scripts{ @Scripts.Render("~/bundles/jqueryval") } 

然后我们必须编写代码来保存对象列表到数据库

 [HttpPost] public ActionResult Index(List<Contact> list) { if (ModelState.IsValid) { using (MyDatabaseEntities dc = new MyDatabaseEntities()) { foreach (var i in list) { var c = dc.Contacts.Where(a =>a.ContactID.Equals(i.ContactID)).FirstOrDefault(); if (c != null) { c.ContactPerson = i.ContactPerson; c.Contactno = i.Contactno; c.EmailID = i.EmailID; } } dc.SaveChanges(); } ViewBag.Message = "Successfully Updated."; return View(list); } else { ViewBag.Message = "Failed ! Please try again."; return View(list); } } 
 using(Html.BeginForm()) { // code here }