Updating PlannerTaskDetails silently fails

2019-07-27 10:30发布

问题:

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?

回答1:

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")



回答2:

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.