Reputation: 23
I am using MVC 4 and I want to get rid of the edit page and just make the change I want on the Index page to multiple items at the same time.
Here is the CSHTML:
@model IEnumerable<HelpDesk.Models.ViewPerm>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>ViewPerm</legend>
<table style="border: 5px solid white;">
<tr>
<th style="border: 5px solid white;">
@Html.DisplayNameFor(model => model.Roles.Role)
</th>
<th style="border: 5px solid white;">
@Html.DisplayNameFor(model => model.Views.Page)
</th>
<th style="border: 5px solid white;">
@Html.DisplayNameFor(model => model.Perm)
</th>
<th></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td style="border: 5px solid white;">
@Html.DisplayFor(modelItem => item.Roles.Role)
</td>
<td style="border: 5px solid white;">
@Html.DisplayFor(modelItem => item.Views.Folder)
@Html.DisplayFor(modelItem => item.Views.Page)
</td>
<td style="border: 5px solid white;">
@Html.EditorFor(modelItem => item.Perm)
</td>
<td>
@Html.ActionLink("Delete", "Delete", new { id = item.VPermID })
</td>
</tr>
}
</table>
<input type="submit" value="Save" />
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
And the C#:
public ActionResult Index()
{
var viewperm = db.ViewPerm.Include(v => v.Roles).Include(v => v.Views);
return View(viewperm.ToList());
}
[HttpPost]
public ActionResult Index(ViewPerm viewperm)
{
if (ModelState.IsValid)
{
db.Entry(viewperm).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewperm);
}
When I hit the save button it says "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries."
Thanks for the help.
Upvotes: 2
Views: 769
Reputation: 56429
First problem: Your view deals with multiple ViewPerm
, yet your post action only takes one.
Change your post method to deal with multiple:
[HttpPost]
public ActionResult Index(IEnumerable<ViewPerm> viewperms)
{
if (ModelState.IsValid)
{
foreach (ViewPerm viewperm in viewperms)
{
db.Entry(viewperm).State = EntityState.Modified;
}
db.SaveChanges();
}
return View(viewperms);
}
Your second problem is that you're using a foreach
to iterate through the items in the Model in your view. The fields need to be indexed correctly so the model binder can do it's stuff (it works on arrays). Change your view to be:
@for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td style="border: 5px solid white;">
@Html.DisplayFor(m => m[i].Roles.Role)
</td>
<td style="border: 5px solid white;">
@Html.DisplayFor(m => m[i].Views.Folder)
@Html.DisplayFor(m => m[i].Views.Page)
</td>
<td style="border: 5px solid white;">
@Html.EditorFor(m => m[i].Perm)
</td>
<td>
@Html.ActionLink("Delete", "Delete", new { id = Model[i].VPermID })
</td>
</tr>
}
Upvotes: 2