I'm developing an ASP.NET MVC 5 web with C# and .NET Framework 4.5.1.
I have this form in a cshtml file:
@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> And this is the action method:
[HttpPost] public ActionResult Save(FormCollection form) { return null; } And the two 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; } } But I get this in FormCollection form var: 
But I want to get an IEnumerable<BatchProductViewModel> model:
public ActionResult Save(int productId, IEnumerable<BatchProductViewModel> model); If I use the above method signature both parameters are null.
I want an IEnumerable because user is going to add more rows dynamically using jQuery.
This is jQuery script:
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"); }); }); Any idea?
I have checked this SO answer, and this article but I don't get my code working.
BatchProductViewModelas well... Also, in your action method, are you sure your intent was to useBatchProductViewModeland notConnectBatchProductViewModel?ConnectBatchProductViewModelIf you want to generate a view for a collection ofBatchProductViewModelthen you view needs to beIEnumerable<BatchProductViewModel>and the POST method parameter needs to be the same (don't useFormCollection) and the controls forBatchProductViewModelneed to be generated in aforloopint productIdwill never be bound because the name of your control isProduct.Id(not productId). If you change the method topublic ActionResult Save(ConnectBatchProductViewModel model)you will see that it is correctly boundIEnumerablebecause I want to add more rows dynamically using jQuery.