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"
}
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:
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);
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
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.