I am having issues with my child object ALWAYS being dirty. How do I fix this?
public ActionResult Edit(int id)
{
ViewData.Model = PressReleaseEdit.AdminGetPressReleaseById(id);
TempData["obj"] = ViewData.Model;
// bind dropdownlist
ViewBag.BoilerPlateList = new SelectList(BoilerPlateList.GetReadOnlyList(), "BoilerPlateId", "Name");
return View();
}
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(FormCollection collection, PressReleaseEdit pe, int id, Guid? radioValue, Guid? highlightImage)
{
PressReleaseEdit mainObject = (PressReleaseEdit)TempData["obj"];
//if (obj == null)
//{
// return RedirectToAction("Edit", new { id=Request.QueryString["id"] });
//}
// pe.PressReleaseId = obj.PressReleaseId;
if (radioValue.HasValue)
pe.PressReleaseDigitalAsset.DigitalAssetGuid = (Guid)radioValue;
// check if object is dirty, rebind values to pe
#region Highlight
if (pe.Highlight.IsDirty)
{ // ALWAYS DIRTY????, // ALWAYS NEW, even if have done nothing to the object...
What makes even less sense, is mainObject.Highlight is NOT dirty... help!
Sorry, mainObject.Highlight IS dirty. So confused.
Remember that on a post-back you are creating a new object graph, and setting its property values based on those in the postback data. Or CslaModelBinder does this for you - but either way, this is what happens.
As a result, all the objects will be dirty because they are all new, and all their properties were just changed.
The easiest way to avoid this is to fetch the object graph, set the property values, and then save the object graph. This does mean hitting the database to get the existing values, but by having those existing values it allows the object to know whether the "new" property values from the postback are actually different from the existing values.
Ultimately that's the key right? Somehow you or the object need to know whether the data in the postback is different from the data in the database - that's the definition of "IsDirty'.
Is this how I would wire this up then?
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(FormCollection collection, PressReleaseEdit pe, int id, Guid? radioValue, Guid? highlightImage)
{
var model = PressReleaseEdit.AdminGetPressReleaseById(id);
model.Highlight = pe.Highlight;
etc.
I show how to do this in the ASP.NET MVC book on page 21. You need to fetch the object, call UpdateModel, and then set any non-public properties.
In other words, you can still use binding, you just need to call it explicitly via UpdateModel.
I was just fighting this same battle and came across this. The code that I think you're talking about on page 21 looks like this:
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var project = ProjectEdit.NewProject();
UpdateModel(project, collection);
LoadProperty(project, ProjectEdit.IdProperty, id);
For project to not be dirty, I think it needs to be:
var project = ProjectEdit.GetProject(id)
right? Just wanted to make sure I'm following you.
Copyright (c) Marimer LLC