Search code examples
c#.netasp.net-coregraphmicrosoft-graph-sdks

DriveItem Patch method with error in Graph Api


I'm creating an API with ASP.NET Core that accesses a list/drive with the graph api and at some point I need to update an item that was created in the drive library to add an ID (which is a custom column), but I'm getting an invalid request error, can anyone help me?

EDIT: I found the problem, apparently it doesn't recognize the additonal fields, when I put only Name it works. How can I update custom fields?

        public async Task<DriveItem?> CreateDriveItem(FileDTO file)
        {
            var fileBytes = Convert.FromBase64String(file.Base64);
            var fileNameWithExtension = file.FileName + file.FileType;

            var requestBody = new CreateUploadSessionPostRequestBody
            {
                Item = new DriveItemUploadableProperties
                {
                    Name = fileNameWithExtension,
                }
            };

            var uploadSession = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).CreateUploadSession.PostAsync(requestBody);

            if (uploadSession == null) { return null; }

            using var stream = new MemoryStream(fileBytes);
            await UploadFileInChunks(uploadSession.UploadUrl ?? "", stream);

            var createdItem = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).GetAsync((requestConfiguration) =>
            {
                requestConfiguration.QueryParameters.Expand = new string[] { "listItem($expand=fields)" };
            });

            if (createdItem == null) { return null; }

            var requestBodyPatch = new DriveItem
            {
                Name = "NomeAtualizado com ID.txt",
                ListItem = new ListItem
                {
                    Fields = new FieldValueSet
                    {
                        AdditionalData = new Dictionary<string, object>
                        {
                            {"ID_Solicitacao", 123 }
                        }
                    }
                }
            };

            var patch = await _graphClient.Graph.Drives[_driveId].Items[createdItem.Id].PatchAsync(requestBodyPatch);

            if (patch == null) { return null; }

            return patch;
        }

and the error is:

{
  "message": "OData error occurred.",
  "details": "Cannot update a listItem via driveItem, patch the listItem directly"
}


Solution

  • In a SharePoint document library, each item is composed of both a DriveItem and a ListItem, which are linked together. To update such an item, you follow these steps:

    Upload the Document:

    First, you upload the document. The response from this upload will include the created DriveItem.

    var uploadSession = await_graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).CreateUploadSession.PostAsync(requestBody);
    

    Retrieve the ListItem ID:

    The DriveItem response contains a property called listItem. This listItem property includes an id, which is the ID of the linked ListItem.

    var createdItem = await _graphClient.Graph.Drives[_driveId].Root.ItemWithPath(fileNameWithExtension).GetAsync((requestConfiguration) =>
    {
        requestConfiguration.QueryParameters.Expand = new string[] { "listItem($expand=fields)" };
    });
    
    createdItem.ListItem?.Id
    

    Update the ListItem:

    Using the listItemId, you can directly update the fields of the ListItem without needing to search for it.

    var fields = new FieldValueSet
        {
          AdditionalData = new Dictionary<string, object>
            {
              {"ID_Solicitacao", 123 }
            }
        };
      
    var patch = await _graphClient.Graph.Sites[_siteId].Lists[_driveListId].Items[createdItem.ListItem?.Id].Fields.PatchAsync(fields);
    

    This method ensures you can efficiently upload a document and update its associated ListItem fields using the provided ID from the upload response.