POST表单数组没有成功
我正在使用C#和.NET Framework 4.5.1开发ASP.NET MVC 5 Web。
我在cshtml
文件中有这个form
:
@model MyProduct.Web.API.Models.ConnectBatchProductViewModel @{ Layout = null; } Create @if (@Model != null) { Producto: @Model.Product.ProductCode, Cantidad: @Model.ExternalCodesForThisProduct
using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post)) { @Html.HiddenFor(model => model.Product.Id, new { @id = "productId", @Name = "productId" }); Cantidad Lote @Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].Quantity") @Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].BatchName")
} } else { Error. }
这是动作方法:
[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 BatchProducts { get; set; } }
但我在FormCollection form
得到了这个:
但我想得到一个IEnumerable model
:
public ActionResult Save(int productId, IEnumerable model);
如果我使用上面的方法签名,则两个参数都为null。
我想要一个IEnumerable
因为用户将使用jQuery动态添加更多行。
这是jQuery
脚本:
jQuery(document).ready(function ($) { var counter = 0; $("#addrow").on("click", function () { counter = $('#batchTable tr').length - 2; var newRow = $(""); var cols = ""; var quantity = 'ConnectBatchProductViewModel.BatchProducts[0].Quantity'.replace(/\[.{1}\]/, '[' + counter + ']'); var batchName = 'ConnectBatchProductViewModel.BatchProducts[0].BatchName'.replace(/\[.{1}\]/, '[' + counter + ']'); cols += ' '; cols += ' '; cols += ' '; 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"); }); });
任何的想法?
我检查了这个SO答案 , 这篇文章,但我没有得到我的代码工作。
您需要在for
循环中生成集合的控件,以便使用索引器正确命名它们(请注意,属性BatchProducts
需要是IList
@using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post)) { ....
然后需要POST方法
public ActionResult Save(ConnectBatchProductViewModel model) { .... }
编辑
注意:在编辑之后,如果要在视图中动态添加和删除BatchProductViewModel
项,则需要使用BeginCollectionItem
帮助程序或html模板,如本答案中所述
动态添加新项目的模板将是
请注意,虚拟索引器和隐藏输入的不匹配值会阻止此模板回发。
然后添加新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()); });
在Post Methode中,您将收到“MyProduct.Web.API.Models.ConnectBatchProductViewModel”作为参数。
将现有模型用于Post方法。
为什么你想从你的模型中获得IEnumerable? 只有一个可用,包括模型中的id。
您可以通过video教程访问本文以获取完整的源代码。
你必须首先创建一个动作,我们可以从中传递对象列表
[HttpGet] public ActionResult Index() { List model = new List (); using (MyDatabaseEntities dc = new MyDatabaseEntities()) { model = dc.Contacts.ToList(); } return View(model); }
然后我们需要为该动作创建一个视图
@model List @{ ViewBag.Title = "Update multiple row at once Using MVC 4 and EF "; } @using (@Html.BeginForm("Index","Home", FormMethod.Post)) { Contact Person Contact No Email ID @for (int i = 0; i < Model.Count; i++) { @Html.HiddenFor(model => model[i].ContactID) @Html.EditorFor(model => model[i].ContactPerson) @Html.EditorFor(model => model[i].Contactno) @Html.EditorFor(model => model[i].EmailID) }
@ViewBag.Message
} @section Scripts{ @Scripts.Render("~/bundles/jqueryval") }
然后我们必须编写用于将对象列表保存到数据库的代码
[HttpPost] public ActionResult Index(List 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 }
遵循DRY原则,您可以为此创建一个EditorTemplate。 脚步:
1-在视图>共享>创建名为( EditorTemplates )的新文件夹
2-在新创建的EditorTemplates文件夹中创建一个视图,视图的模型应该是根据OP示例的BatchProductViewModel。 将代码放在编辑器视图中。 不需要循环或索引。
EditorTemplate将为每个子实体执行类似于PartialView的操作,但方式更为通用。
3-在父实体的视图中,调用编辑器:@ Html.EditorFor(m => m.BatchProducts)
这不仅可以提供更有条理的视图,还可以让您在其他视图中重复使用相同的编辑器。