I am very new at asp.net mvc, so the reason behind my failure might be something basic as well, but I can't seem to find it after nearly a days work now.
What I am trying to do is to get the edited Model from the Index view and pass it to a second action which does not have view and returns return RedirectToAction("Index")
in the related controller. In OrdersItemsController
my Action is as the following:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MarkedShipped(IEnumerable<orders_items> orderItems)
{
if (ModelState.IsValid)
{
foreach (var item in orderItems)
{
unitOfWork.GenericRepository<orders_items>().Update(item);
}
}
return RedirectToAction("Index");
}
And in the Index.cshtml which is in OrdersItems folder in the Views, what I did is as following:
@model IEnumerable<Project.DataAccess.orders_items>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm("MarkedShipped", "OrdersItems", new { orderItems = Model }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.quantity)
</th>
<th>
@Html.DisplayNameFor(model => model.itemprice)
</th>
<th>
@Html.DisplayNameFor(model => model.trackingnumber)
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.quantity)
</td>
<td>
@Html.DisplayFor(modelItem => item.itemprice)
</td>
<td>
@Html.EditorFor(modelItem => item.trackingnumber)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.itemid })
</td>
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="MarkShipped" class="btn btn-default" />
</div>
</div>
}
My problem is, I am not able to get the Model from the view with orderItems parameter, I am not sure if this is the right "syntax" for what I am trying to accomplish; but what I get for orderItems
when the action is called is a List of orders_items
with Count = 0
not a null value.
I have also checked if there is an application level exception, but got no exception from Application_Error
in Global.asax
I am stuck for a day now so If anyone can point me a direction on how to pass the Model (or "the edited data") to the action for me to update the db, I would be very grateful. Thanks.
Firstly you cannot add a model which is a collection (or a model which contains a property which is a complex object or collection) to a forms route parameters. Internally the helper calls the
.ToString()
method and if you inspect the html generated for your form tag you will see something likeand binding will fail since you collection cannot be bound to a string. Even if it did work, it would be rather pointless because it would just post back the original values of the model.
Next, you cannot use a
foreach
loop to generate form controls. Again if you inspect the html your generating you will see that theEditorFor()
method is generating inputs with duplicateid
attributes (invalid html) and duplicatename
attributes which do not have the necessary indexers to bind to a collection when you post. You need to use either afor
loop of a customEditorTemplate
for typeoforders_items
Using a
for
loop means that your model must implementIList<T>
and the view needs to beUsing an
EditorTemplate
, create a partial in/Views/Shared/EditorTemplates/orders_items.cshtml
(note the name of the file must match the name of the class)and then in the main view (you can use
IEnumerable<T>
)The
EditorFor()
method acceptsIEnumerable<T>
and will generate one row for each item in you collection based on the html in theEditorTemplate
In both cases, it you inspect the html you will now see the correct name attributes necessary for you model to bind when you post
You can do the following
In this way each html element gets its own unique id and its possible to retrieve the information back from them individually. You can use for or Foreach. Just make sure that your razor iterator is functioning. You can view the element ids in the source to see if it is working.
Try For instead of foreach here.
Check this :- http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/