Reputation: 1795
To update an entity, I'm using http PUT, passing the updated object as the request body:
PUT /api/flareform/3
{
"JobId" : "12-12-4004",
"Id" : 3,
"Tasks" : [
{
"Hazard" : "Clumsyness",
"Id" : 2,
"FlareFormId" : 3,
"Task" : "Hammering",
"Control" : "Make Someone Else Hold the Nail"
},
{
"Hazard" : "Nails",
"Id" : 3,
"FlareFormId" : 3,
"Task" : "Walking",
"Control" : "Keep area clean."
}
],
"PercentComplete" : null,
"Time" : "3pm",
"Initials" : "JD"
}
This is working correctly if I update a simple property of the object, like the Initials. Is it possible/how do I update, add, delete Tasks. Can do it through this object? What I'd like to do is just pass an updated array of Tasks and have it update/delete/add everything:
PUT /api/flareform/3
{
"JobId" : "12-12-4004",
"Id" : 3,
"Tasks" : [
{
"Hazard" : "NewAndImprovedValue",
"Id" : 2,
"FlareFormId" : 3,
"Task" : "NewAndImprovedValue",
"Control" : "NewAndImprovedValue"
},
{
"Hazard" : "SomeNewItemThatDidntExistBefore",
"FlareFormId" : 3,
"Task" : "NoteTheMissingId",
"Control" : "ShouldAddThisOne"
}
],
"PercentComplete" : null,
"Time" : "3pm",
"Initials" : "JD"
}
Upvotes: 2
Views: 3189
Reputation: 1795
Here's more or less what I ended up using. I'm trying to write this in a more generic way so that I don't have to copy/paste this code for each child property that needs to be updatable...
// PUT api/FlareForm/5
public HttpResponseMessage PutFlareForm(int id, FlareForm flareform)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (id != flareform.Id)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
List<int> previousIds = db.FlareForms.AsNoTracking().FirstOrDefault(ff => ff.Id == id).Tasks.Select(t => t.Id).ToList();
List<int> currentIds = flareform.Tasks.Select(t => t.Id).ToList();
List<int> deletedIds = previousIds
.Except(currentIds).ToList();
foreach (var deletedId in deletedIds)
{
FlareFormTask task = db.FlareFormTasks
.Single(od => od.FlareFormId == flareform.Id && od.Id == deletedId);
db.Entry(task).State = EntityState.Deleted;
}
foreach (var task in flareform.Tasks)
{
if (task.Id == 0)
{
task.FlareFormId = flareform.Id;
db.Entry(task).State = EntityState.Added;
}
else
{
db.Entry(task).State = EntityState.Modified;
}
}
db.Entry(flareform).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
Upvotes: 1
Reputation: 10792
Your Json object looks okay. I believe the culprit to be your DAL. As saving child entities isn't as straight forward as one should think.
I'm assuming your Tasks
are in a one to many relationship with the main object. If so you'll need to manually detect any changes (added, deleted or modified) and apply them.
This tutorial should get you started: http://www.entityframeworktutorial.net/update-one-to-many-entities-in-entity-framework.aspx
Upvotes: 2