Why is my ASP.NET MVC3 Edit
action being given a new object instead of the object to edit?
When I inspect the properties of the object that's given the ID value is the unsaved-value
I've specified in my NHibernate mapping files.
In order to work around this I can query back the object to update from the database and set the properties I want from the object that's passed to the method. But while this works OK for a really simple object with one or two properties it quickly becomes a problem when there are lots of properties and it seems like I'm fighting the system (which, to me, is an indication I'm not doing things the way they're supposed to be done).
My mapping:
<id name="Id" column="Id" type="Guid"
unsaved-value="00000000-0000-0000-0000-000000000000">
My Edit method:
[NHibernateActionFilter]
[HttpPost]
public ActionResult Edit(Status status, Guid id)
{
try
{
if (ModelState.IsValid)
{
var originalStatus = Session.QueryOver<Status>()
.Where(s => s.Id == id)
.SingleOrDefault<Status>();
if (originalStatus == null)
throw new Exception(string.Format("No Status with Id: {0}.", id));
originalStatus.StatusName = status.StatusName;
Session.Update(originalStatus );
return RedirectToAction("Index");
}
}
catch (DataMisalignedException ex)
{
// TODO: Log4Net this
ModelState.AddModelError("", "Unable to save changes. Please try again.");
}
return View(status);
}
*The NHibernateActionFilter
is taken from a series of posts by Ayende on Refactoring toward frictionless & odorless code and gives an ISession to each action in the controller decorated with it. However I don't think that's the cause of the problem.
My problem manifests when trying to edit an item, a StaleObjectException
is thrown:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [TheWorkshop.Web.Models.Status#00000000-0000-0000-0000-000000000000]
the new Guid shows me that the Status mentioned is new and not the object previously returned in order to populate the details view. So it would seem that a new object has been newed up and passed into my Edit ActionResult
, but that's not helpful.
As I've shown above I can code around it, but that's more of a hack than a solution. I would prefer to be able to leave my Edit method like so:
[NHibernateActionFilter]
[HttpPost]
public ActionResult Edit(Status status)
{
try
{
if (ModelState.IsValid)
{
Session.Update(status);
return RedirectToAction("Index");
}
}
catch (DataMisalignedException ex)
{
// TODO: Log4Net this
ModelState.AddModelError("", "Unable to save changes. Please try again.");
}
return View(status);
}
Edit
I have looked at the answer How to handle update entities. NHibernate + ASP.NET MVC but that does pretty much what I've already done and I can't believe the update methods have to be so messy as my attempt.
Also I've looked at what does this error mean in nhibernate; it looks identical to my problem, but I couldn't get any of the answers to work for me, that is the problem still persists.