POST a form array without successful












35















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:
enter image description here



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.










share|improve this question

























  • Please post the code for BatchProductViewModel as well... Also, in your action method, are you sure your intent was to use BatchProductViewModel and not ConnectBatchProductViewModel?

    – Ruslan
    Mar 20 '15 at 7:37













  • @Ruslan Question updated.

    – VansFannel
    Mar 20 '15 at 7:38











  • Your model in the view is ConnectBatchProductViewModel If you want to generate a view for a collection of BatchProductViewModel then you view needs to be IEnumerable<BatchProductViewModel> and the POST method parameter needs to be the same (don't use FormCollection) and the controls for BatchProductViewModel need to be generated in a for loop

    – user3559349
    Mar 20 '15 at 7:42











  • And int productId will never be bound because the name of your control is Product.Id (not productId). If you change the method to public ActionResult Save(ConnectBatchProductViewModel model) you will see that it is correctly bound

    – user3559349
    Mar 20 '15 at 7:45











  • I have updated my question. I have changed the view model and I getting the same result. I want an IEnumerable because I want to add more rows dynamically using jQuery.

    – VansFannel
    Mar 20 '15 at 7:46


















35















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:
enter image description here



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.










share|improve this question

























  • Please post the code for BatchProductViewModel as well... Also, in your action method, are you sure your intent was to use BatchProductViewModel and not ConnectBatchProductViewModel?

    – Ruslan
    Mar 20 '15 at 7:37













  • @Ruslan Question updated.

    – VansFannel
    Mar 20 '15 at 7:38











  • Your model in the view is ConnectBatchProductViewModel If you want to generate a view for a collection of BatchProductViewModel then you view needs to be IEnumerable<BatchProductViewModel> and the POST method parameter needs to be the same (don't use FormCollection) and the controls for BatchProductViewModel need to be generated in a for loop

    – user3559349
    Mar 20 '15 at 7:42











  • And int productId will never be bound because the name of your control is Product.Id (not productId). If you change the method to public ActionResult Save(ConnectBatchProductViewModel model) you will see that it is correctly bound

    – user3559349
    Mar 20 '15 at 7:45











  • I have updated my question. I have changed the view model and I getting the same result. I want an IEnumerable because I want to add more rows dynamically using jQuery.

    – VansFannel
    Mar 20 '15 at 7:46
















35












35








35


7






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:
enter image description here



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.










share|improve this question
















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:
enter image description here



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.







c# html asp.net-mvc forms






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 23 '17 at 12:17









Community

11




11










asked Mar 20 '15 at 7:27









VansFannelVansFannel

20.2k81286503




20.2k81286503













  • Please post the code for BatchProductViewModel as well... Also, in your action method, are you sure your intent was to use BatchProductViewModel and not ConnectBatchProductViewModel?

    – Ruslan
    Mar 20 '15 at 7:37













  • @Ruslan Question updated.

    – VansFannel
    Mar 20 '15 at 7:38











  • Your model in the view is ConnectBatchProductViewModel If you want to generate a view for a collection of BatchProductViewModel then you view needs to be IEnumerable<BatchProductViewModel> and the POST method parameter needs to be the same (don't use FormCollection) and the controls for BatchProductViewModel need to be generated in a for loop

    – user3559349
    Mar 20 '15 at 7:42











  • And int productId will never be bound because the name of your control is Product.Id (not productId). If you change the method to public ActionResult Save(ConnectBatchProductViewModel model) you will see that it is correctly bound

    – user3559349
    Mar 20 '15 at 7:45











  • I have updated my question. I have changed the view model and I getting the same result. I want an IEnumerable because I want to add more rows dynamically using jQuery.

    – VansFannel
    Mar 20 '15 at 7:46





















  • Please post the code for BatchProductViewModel as well... Also, in your action method, are you sure your intent was to use BatchProductViewModel and not ConnectBatchProductViewModel?

    – Ruslan
    Mar 20 '15 at 7:37













  • @Ruslan Question updated.

    – VansFannel
    Mar 20 '15 at 7:38











  • Your model in the view is ConnectBatchProductViewModel If you want to generate a view for a collection of BatchProductViewModel then you view needs to be IEnumerable<BatchProductViewModel> and the POST method parameter needs to be the same (don't use FormCollection) and the controls for BatchProductViewModel need to be generated in a for loop

    – user3559349
    Mar 20 '15 at 7:42











  • And int productId will never be bound because the name of your control is Product.Id (not productId). If you change the method to public ActionResult Save(ConnectBatchProductViewModel model) you will see that it is correctly bound

    – user3559349
    Mar 20 '15 at 7:45











  • I have updated my question. I have changed the view model and I getting the same result. I want an IEnumerable because I want to add more rows dynamically using jQuery.

    – VansFannel
    Mar 20 '15 at 7:46



















Please post the code for BatchProductViewModel as well... Also, in your action method, are you sure your intent was to use BatchProductViewModel and not ConnectBatchProductViewModel?

– Ruslan
Mar 20 '15 at 7:37







Please post the code for BatchProductViewModel as well... Also, in your action method, are you sure your intent was to use BatchProductViewModel and not ConnectBatchProductViewModel?

– Ruslan
Mar 20 '15 at 7:37















@Ruslan Question updated.

– VansFannel
Mar 20 '15 at 7:38





@Ruslan Question updated.

– VansFannel
Mar 20 '15 at 7:38













Your model in the view is ConnectBatchProductViewModel If you want to generate a view for a collection of BatchProductViewModel then you view needs to be IEnumerable<BatchProductViewModel> and the POST method parameter needs to be the same (don't use FormCollection) and the controls for BatchProductViewModel need to be generated in a for loop

– user3559349
Mar 20 '15 at 7:42





Your model in the view is ConnectBatchProductViewModel If you want to generate a view for a collection of BatchProductViewModel then you view needs to be IEnumerable<BatchProductViewModel> and the POST method parameter needs to be the same (don't use FormCollection) and the controls for BatchProductViewModel need to be generated in a for loop

– user3559349
Mar 20 '15 at 7:42













And int productId will never be bound because the name of your control is Product.Id (not productId). If you change the method to public ActionResult Save(ConnectBatchProductViewModel model) you will see that it is correctly bound

– user3559349
Mar 20 '15 at 7:45





And int productId will never be bound because the name of your control is Product.Id (not productId). If you change the method to public ActionResult Save(ConnectBatchProductViewModel model) you will see that it is correctly bound

– user3559349
Mar 20 '15 at 7:45













I have updated my question. I have changed the view model and I getting the same result. I want an IEnumerable because I want to add more rows dynamically using jQuery.

– VansFannel
Mar 20 '15 at 7:46







I have updated my question. I have changed the view model and I getting the same result. I want an IEnumerable because I want to add more rows dynamically using jQuery.

– VansFannel
Mar 20 '15 at 7:46














5 Answers
5






active

oldest

votes


















31














You need to generate the controls for the collection in a for loop so they are correctly named with indexers (note that property BatchProducts needs to be 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>
....
}


Then the POST method needs to be



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


Edit



Note: Further to your edit, if you want to dynamically add and remove BatchProductViewModel items in he view, you will need to use the BeginCollectionItem helper or a html template as discussed in this answer



The template to dynamically add new items would be



<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>


Note the dummy indexers and the non-matching value for the hidden input prevents this template posting back.



Then the script to add a new BatchProducts would be



$("#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());
});





share|improve this answer


























  • I want an IEnumerable because user is going to add more rows dynamically using jQuery.

    – VansFannel
    Mar 20 '15 at 7:53






  • 1





    See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

    – user3559349
    Mar 20 '15 at 7:54













  • Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

    – user3559349
    Mar 20 '15 at 8:04











  • Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

    – user3559349
    Mar 20 '15 at 8:06











  • Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

    – VansFannel
    Mar 20 '15 at 8:22





















0














In your Post Methode you receive "MyProduct.Web.API.Models.ConnectBatchProductViewModel" as Parameter.

Use the existing model for the Post methode.



Why do you want a IEnumerable from your model? there is only one available including the id in the model.






share|improve this answer
























  • I want an IEnumerable because I want to add more rows dynamically using jQuery.

    – VansFannel
    Mar 20 '15 at 7:47











  • then change your model to IEnumerable

    – Andre
    Mar 20 '15 at 8:35



















0














you can visit this article for complete source code with a video tutorial.



you have to create an action first, from where we can pass the list of object



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


then we need to create a view for that action



@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")
}


and then we have to write code for save the list of object to the database



[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);
}
}





share|improve this answer































    0

















    using(Html.BeginForm())
    {
    // code here

    }





    While to Post form Data all tags must be included form tag.






    share|improve this answer































      0














      Following the principle of DRY, you can create one EditorTemplate for that purpose.
      Steps:



      1- In Views > Shared > Create new folder named (EditorTemplates)



      2- Create a view inside your newly created EditorTemplates folder , the view's model should be BatchProductViewModel according to the OP example. Place your code inside the Editor view. No loop or index is required.



      An EditorTemplate will act similar to a PartialView for every child entity but in a more generic way.



      3- In your parent entity's view, call your Editor :
      @Html.EditorFor(m => m.BatchProducts)



      Not only this provides a more organized views, but also let's you re-use the same editor in other views as well.






      share|improve this answer























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f29161481%2fpost-a-form-array-without-successful%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        31














        You need to generate the controls for the collection in a for loop so they are correctly named with indexers (note that property BatchProducts needs to be 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>
        ....
        }


        Then the POST method needs to be



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


        Edit



        Note: Further to your edit, if you want to dynamically add and remove BatchProductViewModel items in he view, you will need to use the BeginCollectionItem helper or a html template as discussed in this answer



        The template to dynamically add new items would be



        <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>


        Note the dummy indexers and the non-matching value for the hidden input prevents this template posting back.



        Then the script to add a new BatchProducts would be



        $("#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());
        });





        share|improve this answer


























        • I want an IEnumerable because user is going to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:53






        • 1





          See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

          – user3559349
          Mar 20 '15 at 7:54













        • Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

          – user3559349
          Mar 20 '15 at 8:04











        • Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

          – user3559349
          Mar 20 '15 at 8:06











        • Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

          – VansFannel
          Mar 20 '15 at 8:22


















        31














        You need to generate the controls for the collection in a for loop so they are correctly named with indexers (note that property BatchProducts needs to be 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>
        ....
        }


        Then the POST method needs to be



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


        Edit



        Note: Further to your edit, if you want to dynamically add and remove BatchProductViewModel items in he view, you will need to use the BeginCollectionItem helper or a html template as discussed in this answer



        The template to dynamically add new items would be



        <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>


        Note the dummy indexers and the non-matching value for the hidden input prevents this template posting back.



        Then the script to add a new BatchProducts would be



        $("#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());
        });





        share|improve this answer


























        • I want an IEnumerable because user is going to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:53






        • 1





          See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

          – user3559349
          Mar 20 '15 at 7:54













        • Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

          – user3559349
          Mar 20 '15 at 8:04











        • Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

          – user3559349
          Mar 20 '15 at 8:06











        • Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

          – VansFannel
          Mar 20 '15 at 8:22
















        31












        31








        31







        You need to generate the controls for the collection in a for loop so they are correctly named with indexers (note that property BatchProducts needs to be 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>
        ....
        }


        Then the POST method needs to be



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


        Edit



        Note: Further to your edit, if you want to dynamically add and remove BatchProductViewModel items in he view, you will need to use the BeginCollectionItem helper or a html template as discussed in this answer



        The template to dynamically add new items would be



        <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>


        Note the dummy indexers and the non-matching value for the hidden input prevents this template posting back.



        Then the script to add a new BatchProducts would be



        $("#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());
        });





        share|improve this answer















        You need to generate the controls for the collection in a for loop so they are correctly named with indexers (note that property BatchProducts needs to be 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>
        ....
        }


        Then the POST method needs to be



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


        Edit



        Note: Further to your edit, if you want to dynamically add and remove BatchProductViewModel items in he view, you will need to use the BeginCollectionItem helper or a html template as discussed in this answer



        The template to dynamically add new items would be



        <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>


        Note the dummy indexers and the non-matching value for the hidden input prevents this template posting back.



        Then the script to add a new BatchProducts would be



        $("#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());
        });






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 23 '17 at 12:25









        Community

        11




        11










        answered Mar 20 '15 at 7:50







        user3559349




















        • I want an IEnumerable because user is going to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:53






        • 1





          See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

          – user3559349
          Mar 20 '15 at 7:54













        • Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

          – user3559349
          Mar 20 '15 at 8:04











        • Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

          – user3559349
          Mar 20 '15 at 8:06











        • Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

          – VansFannel
          Mar 20 '15 at 8:22





















        • I want an IEnumerable because user is going to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:53






        • 1





          See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

          – user3559349
          Mar 20 '15 at 7:54













        • Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

          – user3559349
          Mar 20 '15 at 8:04











        • Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

          – user3559349
          Mar 20 '15 at 8:06











        • Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

          – VansFannel
          Mar 20 '15 at 8:22



















        I want an IEnumerable because user is going to add more rows dynamically using jQuery.

        – VansFannel
        Mar 20 '15 at 7:53





        I want an IEnumerable because user is going to add more rows dynamically using jQuery.

        – VansFannel
        Mar 20 '15 at 7:53




        1




        1





        See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

        – user3559349
        Mar 20 '15 at 7:54







        See update to some techniques to do this (and it does not need IEnumerable<T> - it can just as easily be IList<T>)

        – user3559349
        Mar 20 '15 at 7:54















        Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

        – user3559349
        Mar 20 '15 at 8:04





        Note that your model does not have a property named ConnectBatchProductViewModel so ConnectBatchProductViewModel.BatchProducts[#].Quantity wont bind to anything. It needs to be BatchProducts[#].Quantity in order to bind.

        – user3559349
        Mar 20 '15 at 8:04













        Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

        – user3559349
        Mar 20 '15 at 8:06





        Next, you don't generate a <input name="BatchProducts.Index" value="#" /> control for each item, so as soon as you delete an item, binding will fail.

        – user3559349
        Mar 20 '15 at 8:06













        Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

        – VansFannel
        Mar 20 '15 at 8:22







        Without adding BeginCollectionItem and using <td>@Html.TextBox("BatchProducts[0].Quantity")</td> it works. I get a all data correctly inside the ConnectBatchProductViewModel model parameter. But if I have three rows and user deletes second row, I don't get all data in model parameter.

        – VansFannel
        Mar 20 '15 at 8:22















        0














        In your Post Methode you receive "MyProduct.Web.API.Models.ConnectBatchProductViewModel" as Parameter.

        Use the existing model for the Post methode.



        Why do you want a IEnumerable from your model? there is only one available including the id in the model.






        share|improve this answer
























        • I want an IEnumerable because I want to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:47











        • then change your model to IEnumerable

          – Andre
          Mar 20 '15 at 8:35
















        0














        In your Post Methode you receive "MyProduct.Web.API.Models.ConnectBatchProductViewModel" as Parameter.

        Use the existing model for the Post methode.



        Why do you want a IEnumerable from your model? there is only one available including the id in the model.






        share|improve this answer
























        • I want an IEnumerable because I want to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:47











        • then change your model to IEnumerable

          – Andre
          Mar 20 '15 at 8:35














        0












        0








        0







        In your Post Methode you receive "MyProduct.Web.API.Models.ConnectBatchProductViewModel" as Parameter.

        Use the existing model for the Post methode.



        Why do you want a IEnumerable from your model? there is only one available including the id in the model.






        share|improve this answer













        In your Post Methode you receive "MyProduct.Web.API.Models.ConnectBatchProductViewModel" as Parameter.

        Use the existing model for the Post methode.



        Why do you want a IEnumerable from your model? there is only one available including the id in the model.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 20 '15 at 7:44









        AndreAndre

        368412




        368412













        • I want an IEnumerable because I want to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:47











        • then change your model to IEnumerable

          – Andre
          Mar 20 '15 at 8:35



















        • I want an IEnumerable because I want to add more rows dynamically using jQuery.

          – VansFannel
          Mar 20 '15 at 7:47











        • then change your model to IEnumerable

          – Andre
          Mar 20 '15 at 8:35

















        I want an IEnumerable because I want to add more rows dynamically using jQuery.

        – VansFannel
        Mar 20 '15 at 7:47





        I want an IEnumerable because I want to add more rows dynamically using jQuery.

        – VansFannel
        Mar 20 '15 at 7:47













        then change your model to IEnumerable

        – Andre
        Mar 20 '15 at 8:35





        then change your model to IEnumerable

        – Andre
        Mar 20 '15 at 8:35











        0














        you can visit this article for complete source code with a video tutorial.



        you have to create an action first, from where we can pass the list of object



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


        then we need to create a view for that action



        @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")
        }


        and then we have to write code for save the list of object to the database



        [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);
        }
        }





        share|improve this answer




























          0














          you can visit this article for complete source code with a video tutorial.



          you have to create an action first, from where we can pass the list of object



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


          then we need to create a view for that action



          @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")
          }


          and then we have to write code for save the list of object to the database



          [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);
          }
          }





          share|improve this answer


























            0












            0








            0







            you can visit this article for complete source code with a video tutorial.



            you have to create an action first, from where we can pass the list of object



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


            then we need to create a view for that action



            @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")
            }


            and then we have to write code for save the list of object to the database



            [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);
            }
            }





            share|improve this answer













            you can visit this article for complete source code with a video tutorial.



            you have to create an action first, from where we can pass the list of object



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


            then we need to create a view for that action



            @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")
            }


            and then we have to write code for save the list of object to the database



            [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);
            }
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jun 29 '16 at 4:52









            Sourav MondalSourav Mondal

            335413




            335413























                0

















                using(Html.BeginForm())
                {
                // code here

                }





                While to Post form Data all tags must be included form tag.






                share|improve this answer




























                  0

















                  using(Html.BeginForm())
                  {
                  // code here

                  }





                  While to Post form Data all tags must be included form tag.






                  share|improve this answer


























                    0












                    0








                    0










                    using(Html.BeginForm())
                    {
                    // code here

                    }





                    While to Post form Data all tags must be included form tag.






                    share|improve this answer
















                    using(Html.BeginForm())
                    {
                    // code here

                    }





                    While to Post form Data all tags must be included form tag.






                    using(Html.BeginForm())
                    {
                    // code here

                    }





                    using(Html.BeginForm())
                    {
                    // code here

                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 13 '16 at 18:33









                    Mahesh PullaguraMahesh Pullagura

                    113




                    113























                        0














                        Following the principle of DRY, you can create one EditorTemplate for that purpose.
                        Steps:



                        1- In Views > Shared > Create new folder named (EditorTemplates)



                        2- Create a view inside your newly created EditorTemplates folder , the view's model should be BatchProductViewModel according to the OP example. Place your code inside the Editor view. No loop or index is required.



                        An EditorTemplate will act similar to a PartialView for every child entity but in a more generic way.



                        3- In your parent entity's view, call your Editor :
                        @Html.EditorFor(m => m.BatchProducts)



                        Not only this provides a more organized views, but also let's you re-use the same editor in other views as well.






                        share|improve this answer




























                          0














                          Following the principle of DRY, you can create one EditorTemplate for that purpose.
                          Steps:



                          1- In Views > Shared > Create new folder named (EditorTemplates)



                          2- Create a view inside your newly created EditorTemplates folder , the view's model should be BatchProductViewModel according to the OP example. Place your code inside the Editor view. No loop or index is required.



                          An EditorTemplate will act similar to a PartialView for every child entity but in a more generic way.



                          3- In your parent entity's view, call your Editor :
                          @Html.EditorFor(m => m.BatchProducts)



                          Not only this provides a more organized views, but also let's you re-use the same editor in other views as well.






                          share|improve this answer


























                            0












                            0








                            0







                            Following the principle of DRY, you can create one EditorTemplate for that purpose.
                            Steps:



                            1- In Views > Shared > Create new folder named (EditorTemplates)



                            2- Create a view inside your newly created EditorTemplates folder , the view's model should be BatchProductViewModel according to the OP example. Place your code inside the Editor view. No loop or index is required.



                            An EditorTemplate will act similar to a PartialView for every child entity but in a more generic way.



                            3- In your parent entity's view, call your Editor :
                            @Html.EditorFor(m => m.BatchProducts)



                            Not only this provides a more organized views, but also let's you re-use the same editor in other views as well.






                            share|improve this answer













                            Following the principle of DRY, you can create one EditorTemplate for that purpose.
                            Steps:



                            1- In Views > Shared > Create new folder named (EditorTemplates)



                            2- Create a view inside your newly created EditorTemplates folder , the view's model should be BatchProductViewModel according to the OP example. Place your code inside the Editor view. No loop or index is required.



                            An EditorTemplate will act similar to a PartialView for every child entity but in a more generic way.



                            3- In your parent entity's view, call your Editor :
                            @Html.EditorFor(m => m.BatchProducts)



                            Not only this provides a more organized views, but also let's you re-use the same editor in other views as well.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Oct 15 '18 at 22:48









                            Mohamed NagiebMohamed Nagieb

                            20136




                            20136






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f29161481%2fpost-a-form-array-without-successful%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Florida Star v. B. J. F.

                                Danny Elfman

                                Lugert, Oklahoma