POST a form array without successful
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.
c# html asp.net-mvc forms
add a comment |
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.
c# html asp.net-mvc forms
Please post the code forBatchProductViewModel
as well... Also, in your action method, are you sure your intent was to useBatchProductViewModel
and notConnectBatchProductViewModel
?
– Ruslan
Mar 20 '15 at 7:37
@Ruslan Question updated.
– VansFannel
Mar 20 '15 at 7:38
Your model in the view isConnectBatchProductViewModel
If you want to generate a view for a collection ofBatchProductViewModel
then you view needs to beIEnumerable<BatchProductViewModel>
and the POST method parameter needs to be the same (don't useFormCollection
) and the controls forBatchProductViewModel
need to be generated in afor
loop
– user3559349
Mar 20 '15 at 7:42
Andint productId
will 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 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 anIEnumerable
because I want to add more rows dynamically using jQuery.
– VansFannel
Mar 20 '15 at 7:46
add a comment |
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.
c# html asp.net-mvc forms
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.
c# html asp.net-mvc forms
c# html asp.net-mvc forms
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 forBatchProductViewModel
as well... Also, in your action method, are you sure your intent was to useBatchProductViewModel
and notConnectBatchProductViewModel
?
– Ruslan
Mar 20 '15 at 7:37
@Ruslan Question updated.
– VansFannel
Mar 20 '15 at 7:38
Your model in the view isConnectBatchProductViewModel
If you want to generate a view for a collection ofBatchProductViewModel
then you view needs to beIEnumerable<BatchProductViewModel>
and the POST method parameter needs to be the same (don't useFormCollection
) and the controls forBatchProductViewModel
need to be generated in afor
loop
– user3559349
Mar 20 '15 at 7:42
Andint productId
will 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 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 anIEnumerable
because I want to add more rows dynamically using jQuery.
– VansFannel
Mar 20 '15 at 7:46
add a comment |
Please post the code forBatchProductViewModel
as well... Also, in your action method, are you sure your intent was to useBatchProductViewModel
and notConnectBatchProductViewModel
?
– Ruslan
Mar 20 '15 at 7:37
@Ruslan Question updated.
– VansFannel
Mar 20 '15 at 7:38
Your model in the view isConnectBatchProductViewModel
If you want to generate a view for a collection ofBatchProductViewModel
then you view needs to beIEnumerable<BatchProductViewModel>
and the POST method parameter needs to be the same (don't useFormCollection
) and the controls forBatchProductViewModel
need to be generated in afor
loop
– user3559349
Mar 20 '15 at 7:42
Andint productId
will 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 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 anIEnumerable
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
add a comment |
5 Answers
5
active
oldest
votes
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());
});
I want anIEnumerable
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 needIEnumerable<T>
- it can just as easily beIList<T>
)
– user3559349
Mar 20 '15 at 7:54
Note that your model does not have a property namedConnectBatchProductViewModel
soConnectBatchProductViewModel.BatchProducts[#].Quantity
wont bind to anything. It needs to beBatchProducts[#].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 addingBeginCollectionItem
and using<td>@Html.TextBox("BatchProducts[0].Quantity")</td>
it works. I get a all data correctly inside theConnectBatchProductViewModel model
parameter. But if I have three rows and user deletes second row, I don't get all data inmodel
parameter.
– VansFannel
Mar 20 '15 at 8:22
|
show 4 more comments
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.
I want anIEnumerable
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
add a comment |
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);
}
}
add a comment |
using(Html.BeginForm())
{
// code here
}
While to Post form Data all tags must be included form tag.
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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());
});
I want anIEnumerable
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 needIEnumerable<T>
- it can just as easily beIList<T>
)
– user3559349
Mar 20 '15 at 7:54
Note that your model does not have a property namedConnectBatchProductViewModel
soConnectBatchProductViewModel.BatchProducts[#].Quantity
wont bind to anything. It needs to beBatchProducts[#].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 addingBeginCollectionItem
and using<td>@Html.TextBox("BatchProducts[0].Quantity")</td>
it works. I get a all data correctly inside theConnectBatchProductViewModel model
parameter. But if I have three rows and user deletes second row, I don't get all data inmodel
parameter.
– VansFannel
Mar 20 '15 at 8:22
|
show 4 more comments
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());
});
I want anIEnumerable
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 needIEnumerable<T>
- it can just as easily beIList<T>
)
– user3559349
Mar 20 '15 at 7:54
Note that your model does not have a property namedConnectBatchProductViewModel
soConnectBatchProductViewModel.BatchProducts[#].Quantity
wont bind to anything. It needs to beBatchProducts[#].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 addingBeginCollectionItem
and using<td>@Html.TextBox("BatchProducts[0].Quantity")</td>
it works. I get a all data correctly inside theConnectBatchProductViewModel model
parameter. But if I have three rows and user deletes second row, I don't get all data inmodel
parameter.
– VansFannel
Mar 20 '15 at 8:22
|
show 4 more comments
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());
});
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());
});
edited May 23 '17 at 12:25
Community♦
11
11
answered Mar 20 '15 at 7:50
user3559349
I want anIEnumerable
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 needIEnumerable<T>
- it can just as easily beIList<T>
)
– user3559349
Mar 20 '15 at 7:54
Note that your model does not have a property namedConnectBatchProductViewModel
soConnectBatchProductViewModel.BatchProducts[#].Quantity
wont bind to anything. It needs to beBatchProducts[#].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 addingBeginCollectionItem
and using<td>@Html.TextBox("BatchProducts[0].Quantity")</td>
it works. I get a all data correctly inside theConnectBatchProductViewModel model
parameter. But if I have three rows and user deletes second row, I don't get all data inmodel
parameter.
– VansFannel
Mar 20 '15 at 8:22
|
show 4 more comments
I want anIEnumerable
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 needIEnumerable<T>
- it can just as easily beIList<T>
)
– user3559349
Mar 20 '15 at 7:54
Note that your model does not have a property namedConnectBatchProductViewModel
soConnectBatchProductViewModel.BatchProducts[#].Quantity
wont bind to anything. It needs to beBatchProducts[#].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 addingBeginCollectionItem
and using<td>@Html.TextBox("BatchProducts[0].Quantity")</td>
it works. I get a all data correctly inside theConnectBatchProductViewModel model
parameter. But if I have three rows and user deletes second row, I don't get all data inmodel
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
|
show 4 more comments
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.
I want anIEnumerable
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
add a comment |
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.
I want anIEnumerable
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
add a comment |
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.
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.
answered Mar 20 '15 at 7:44
AndreAndre
368412
368412
I want anIEnumerable
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
add a comment |
I want anIEnumerable
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
add a comment |
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);
}
}
add a comment |
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);
}
}
add a comment |
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);
}
}
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);
}
}
answered Jun 29 '16 at 4:52
Sourav MondalSourav Mondal
335413
335413
add a comment |
add a comment |
using(Html.BeginForm())
{
// code here
}
While to Post form Data all tags must be included form tag.
add a comment |
using(Html.BeginForm())
{
// code here
}
While to Post form Data all tags must be included form tag.
add a comment |
using(Html.BeginForm())
{
// code here
}
While to Post form Data all tags must be included form tag.
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
}
answered Aug 13 '16 at 18:33
Mahesh PullaguraMahesh Pullagura
113
113
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Oct 15 '18 at 22:48
Mohamed NagiebMohamed Nagieb
20136
20136
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Please post the code for
BatchProductViewModel
as well... Also, in your action method, are you sure your intent was to useBatchProductViewModel
and notConnectBatchProductViewModel
?– 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 ofBatchProductViewModel
then you view needs to beIEnumerable<BatchProductViewModel>
and the POST method parameter needs to be the same (don't useFormCollection
) and the controls forBatchProductViewModel
need to be generated in afor
loop– user3559349
Mar 20 '15 at 7:42
And
int productId
will 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 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