Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Client bug]: PATCH Planner.Tasks[id].Details ChecklistItems Odata Type not serializing correctly. #1933

Closed
WadeTheFade opened this issue May 25, 2023 · 3 comments

Comments

@WadeTheFade
Copy link

WadeTheFade commented May 25, 2023

Describe the bug
When updating a planner task, it fails with the following error:

The request is invalid:
Value cannot be null.
Parameter name: qualifiedName

To Reproduce
Steps to reproduce the behavior:
This is very similar to #1729 . All steps to reproduce can be done the exact same way except with Checklist in PlannerTaskDetails.

The simplest representation of my code is:

var plannerTaskDetails = await _graphServiceClient.Planner.Tasks[task.Id].Details.GetAsync();
plannerTaskDetails.Checklist.AdditionalData = checklistItems; //Dictionary<string,object>();
await _graphServiceClient.Planner.Tasks[task.Id].Details.PatchAsync(plannerTaskDetails);

I was not able to implement the workaround listed for this as I was updating an existing planner by adding a checklist to it. In trying to work around many other properties not serializing correctly with the same behavior (Checklist for one)
I copy/pasted the example from the documentation on PlannerTaskDetails and it still failed to Patch.

Expected behavior
The OdataType should be serialized to @odata.type.
The OrderHint should be serialized to orderHint.
The IsChecked should be serialized to isChecked.

Client version
5.11.0

Desktop (please complete the following information):

  • OS: Windows 10

Additional context
This is some of the modeling I was doing to get around the Bad Request errors during attempting the work around:

   public class CheckListItem
    {
        [JsonPropertyName("displayName")]
        public string DisplayName { get; set; }
        [JsonPropertyName("orderHint")]
        public string OrderHint { get; set; } = " !";
        [JsonPropertyName("@odata.type")]
        public string OdataType { get; set; }
        [JsonPropertyName("isChecked")]
        public bool IsChecked { get; set; } = false;
    }
    public class PlannerTaskDetails
    {
        [JsonPropertyName("checklist")]
        public PlannerChecklistItems Checklist { get; set; }
        [JsonPropertyName("previewType")]
        public string PreviewType { get; set; }
    }
    public class PlannerChecklistItems
    {
        public Dictionary<string, object> AdditionalData { get; set; }
        
    }
@ghost ghost added the Needs: Triage label May 25, 2023
@WadeTheFade WadeTheFade changed the title [Client bug]: PATCH Plan.Planner.Details ChecklistItems Odata Type not serializing correctly. [Client bug]: PATCH Planner.Tasks[id].Details ChecklistItems Odata Type not serializing correctly. May 25, 2023
@WadeTheFade
Copy link
Author

An update: I took the normal request we'd be passing in above: await _graphServiceClient.Planner.Tasks[task.Id].Details.PatchAsync(plannerTaskDetails);

And serialized it to match this model 1:1 to my own custom model serializing the properties into what the end point is requesting. A lot of trial and error went into find the expected property values.

In the end I still landed on the error:

{
   "error":{
      "code":"",
      "message":"The request is invalid:\r\nValue cannot be null.\r\nParameter name: qualifiedName",
      "innerError":{
         "date":"2023-06-15T20:47:51",
         "request-id":"34baf7a7-db2d-40e0-8e12-8834625b2fb4",
         "client-request-id":"9679923a-242c-47b0-af15-db0db13689bb"
      }
   }
}

Here is my full modeling:

    public class CheckListItem
    {
        [JsonPropertyName("title")]
        public string DisplayName { get; set; }
        [JsonPropertyName("orderHint")]
        public string OrderHint { get; set; } = " !";
        [JsonPropertyName("@odata.type")]
        public string OdataType { get; set; }
        [JsonPropertyName("isChecked")]
        public bool IsChecked { get; set; } = false;
    }
    public class PlannerTaskDetails
    {
        [JsonPropertyName("checklist")]
        public PlannerChecklistItems Checklist { get; set; }
        [JsonPropertyName("previewType")]
        public string PreviewType { get; set; }
        [JsonPropertyName("additionalData")]
        public Dictionary<string, object> AdditionalData { get; set; }  = new Dictionary<string, object>();
        [JsonPropertyName("id")]
        public string Id{ get; set; }
        [JsonPropertyName("backingStore")]
        public IBackingStore BackingStore { get; set; }
        [JsonPropertyName("@odata.type")]
        public string OdataType { get; set; } = "microsoft.graph.plannerTaskDetails";
    }
    public class PlannerChecklistItems
    {
        [JsonPropertyName("additionalData")]
        public Dictionary<string, object> AdditionalData { get; set; } = new Dictionary<string, object>();
        [JsonPropertyName("backingStore")]
        public IBackingStore BackingStore { get; set; }
    }

My request:

{
   "checklist":{
      "additionalData":{
         "1e105d6d-21f3-44ef-9048-a2461d269375":{
            "title":"Project Approval",
            "orderHint":" !",
            "@odata.type":"microsoft.graph.plannerChecklistItem",
            "isChecked":false
         }
      },
      "backingStore":{
         "InitializationCompleted":true,
         "ReturnOnlyChangedValues":false
      }
   },
   "previewType":"Checklist",
   "additionalData":{
      "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#planner/tasks(\u0027lmnN9NwhiE-SDm6nzQ0IsWQAA1ZM\u0027)/details/$entity",
      "@odata.etag":"W/\u0022JzEtVGFza0RldGFpbHMgQEBAQEBAQEBAQEBAQEBARCc=\u0022"
   },
   "id":"lmnN9NwhiE-SDm6nzQ0IsWQAA1ZM",
   "backingStore":{
      "InitializationCompleted":true,
      "ReturnOnlyChangedValues":false
   },
   "@odata.type":"microsoft.graph.plannerTaskDetails"
}

(note: it was complaining about PlannerTaskDetails.ODataType being null so I had to fill it out with something - even though its missing from documentation, so I guessed at the value)

Relevant part of the work around described in bug ticket above:

var plannerTaskDetails = await _graphServiceClient.Planner.Tasks[task.Id].Details.GetAsync();
var checklistItems = new Dictionary<string, object>();
                    foreach(var c in t.Checklist)
                    {
                       checklistItems.Add(Guid.NewGuid().ToString(), new CheckListItem { OdataType = "microsoft.graph.plannerChecklistItem", DisplayName = c.Title });
                        
                    }
plannerTaskDetails.Checklist.AdditionalData = checklistItems;
httpClient.DefaultRequestHeaders.Add("If-Match", plannerTaskDetails.AdditionalData["@odata.etag"].ToString());

var jsonPayload = System.Text.Json.JsonSerializer.Serialize(requestBody);
var requestContent = new StringContent(jsonPayload, Encoding.UTF8, "application/json");

var response = await httpClient.PatchAsync($"planner/tasks/{task.Id}/details", requestContent);
var responseContent = await response.Content.ReadAsStringAsync();

@andrueastman I've tried to fork this repo to replicate the Model you added in PR #1754 (specifically this commit) for ChecklistItems, however, I can't load the solution in VS2022 as it complains about a file path being too long. No matter what setting I change on my corporate machine won't allow long file names.

@mmamfgm
Copy link

mmamfgm commented Jul 17, 2023

I have the same issue, hope this will be fixed soon. For now, we will stick with the v4 Graph SDK. @andrueastman the same problem is happening with PlannerExternalReferences.

@andrueastman
Copy link
Member

Closing as duplicate of #2050. Resolved with #2095

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants