I'm using the Microsoft Graph .Net SDK to interact with Planner.
I've just created a PlannerTask
, and I'd like to set the Description property.
My approach for this is covered in: How can I create a planner task with a description?
Here's the code which takes the returned PlannerTaskDetails
object, modifies the Description, and then updates it:
var taskDetails = taskDetailsResult.Result; // Get Previous Task Details
taskDetails.Description = description;
task.Details = await graphServiceClient
.Planner
.Tasks[task.Id]
.Details
.Request()
.Header("If-Match", taskDetails.GetEtag())
.UpdateAsync(taskDetails);
UpdateAsync returns, but it returns a null.
There's no exception, the null obviously contains no further information, and the Description is not changed.
I used Fiddler to monitor the HTTP traffic going back and forth. I can see that a PATCH
request is being sent to the Graph API, and it has the If-Match
header set.
Oddly, the JSON object in the request body has the description property listed twice! The first time with my value, and the second time with a null.
I assume the deserializer is taking the last value it sees for a property, and so that's why it doesn't update.
What am I doing wrong?
You correctly changed your code to use a patch object instead of reusing the existing PlannerTaskDetail
. To get back the updated object (if this is supported), you'll need to set the prefer header.
http://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part1-protocol/odata-v4.0-errata03-os-part1-protocol-complete.html#_Toc453752234, section 8.2.8.7
.Header("prefer", "return=representation")
I wondered if trying to re-use the retrieved PlannerTaskDetails
object was causing the "set twice" behavior I was seeing with the Description property.
I tweaked my code to create a new PlannerTaskDetails
object, while still using the e-tag from the retrieved PlannerTaskDetails
object, and this time the only properties in the JSON body was a single instance of the Description property with my desired value.
var previousTaskDetails = taskDetailsResult.Result; // Get Previous Task Details
var newTaskDetails = new PlannerTaskDetails();
newTaskDetails.Description = description;
task.Details = await graphServiceClient
.Planner
.Tasks[task.Id]
.Details
.Request()
.Header("If-Match", previousTaskDetails.GetEtag())
.UpdateAsync(newTaskDetails);
UpdateAsync
still returns a null object, so if I wanted to return the latest PlannerTaskDetails
object along with the PlannerTask
object the number API calls is now up to 4:
- Create Task.
- Retrieve TaskDetails.
- Update TaskDetails.
- Retrieve TaskDetails.