This is a follow up to a question that was asked yesterday.
I have a viewmodel, which shows a list of objectives. Using jquery I can add a new objectives line to the screen (the ID is set to 0 for any new objectives listed). When I click on the Save button to Post the objective list back to the controller, the controller loops through the objective list, and checks the ID against the database. If the ID is NOT found, it creates a new objective, adds this to the DB context, and saves te changes. It then retreives the ID, and returns the View(model) to the View.
The problem is, although the ID in the model, is updated to the database ID – when the model is rendered in the View again, it’s ID is still 0. So if I click Save again, it again, re-adds the “new objective added previously” to the database again.
My controller is shown below:
//
// POST: /Objective/Edit/model
[HttpPost]
public ActionResult Edit(ObjectivesEdit model)
{
if (model.Objectives != null)
{
foreach (var item in model.Objectives)
{
// find the database row
Objective objective = db.objectives.Find(item.ID);
if (objective != null) // if database row is found...
{
objective.objective = item.objective;
objective.score = item.score;
objective.possscore = item.possscore;
objective.comments = item.comments;
db.SaveChanges();
}
else // database row not found, so create a new objective
{
Objective obj = new Objective();
obj.comments=item.comments;
obj.objective = item.objective;
obj.possscore = item.possscore;
obj.score = item.score;
db.objectives.Add(obj);
db.SaveChanges();
// now get the newly created ID
item.ID = obj.ID;
}
}
}
return View(model);
}
My ID is being set in the controller:

EDIT: Another example here, showing model.Objectives1.ID being updated:

However when the view renders it, it reverts to 0:

The Objectives list is determined as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcObjectives2.Models
{
public class ObjectivesEdit
{
public IEnumerable<Objective> Objectives { set; get; }
public ObjectivesEdit()
{
if (Objectives == null)
Objectives = new List<Objective>();
}
}
}
The View has:
@model MvcObjectives2.Models.ObjectivesEdit
@using (Html.BeginForm())
{
@Html.EditorFor(x=>x.Objectives)
<button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> Save</button>
}
and in my EditorTemplate (objective.cshtml):
@model MvcObjectives2.Models.Objective
<div class="objec">
<div>
@Html.TextBoxFor(x => x.objective})
</div>
<div>
@Html.TextBoxFor(x => x.score})
</div>
<div>
@Html.TextBoxFor(x => x.possscore})
</div>
<div>
@Html.TextBoxFor(x => x.comments})
@Html.HiddenFor(x => x.ID) // This is the ID where it should now show the new ID from the database, but shows 0
</div>
</div>
I suspect the issue is somewhere in my controller – but I would appreciate any advise on how to get my View to render the new ID of the added objective.
After rewording my search, I came across several posts which say this is by design. A Posted form expects to display what it sent to the controller, if the same page is shown again.
However, you can add this, which will flush ModelState, and apparantly show the updated values from the model, updated in the controller:
I’m not certain if this has any other effect yet – but for now, it appears to work ok.
Thanks, Mark