John Källén
John Källén

Reputation: 7973

How to delete multiple drive items in a batch using GraphAPI SDK

I want to delete a few dozen or so items in a SharePoint document library using the Graph API SDK. I can delete them individually like this:

for (var item in driveItems) {
    await clientCtx
        .Sites[site.Id]
        .Drives[drive.Id]
        .Items[item.Id]
        .Request()
        .DeleteAsync();
}

but as the number of items may grow, this becomes slow. Is there anyway to delete multiple items in one blast/batch?

I'm constrained to use the Graph API SDK and C# -- I'm not allowed to form HTTP/JSON queries manually.

Upvotes: 0

Views: 23

Answers (1)

user2250152
user2250152

Reputation: 20788

You will have to use batch request. The Graph .NET SDK v5 has the BatchRequestContentCollection which represents a collection of all batch requests. Inside each batch request you can have 20 requests.

static async Task RemoveFiles(GraphServiceClient client, string driveId, List<string> fileIds)
{
    var batchCollection = new BatchRequestContentCollection(client);
    for (int i = 0; i < fileIds.Count; i += 20)
    {
        var selectedFileIds = fileIds.Skip(i).Take(20);
        foreach (var fileId in selectedFileIds)
        {
            // to delete the file permanently, use the following request instead
            var request = client.Drives[driveId].Items[fileId].PermanentDelete.ToPostRequestInformation();
            // to move the file to the recycle bin, use the following request instead
            // var request = client.Drives[driveId].Items[fileId].ToDeleteRequestInformation();
            await batchCollection.AddBatchRequestStepAsync(request, fileId);
        }
    }
    var batchResponse = await client.Batch.PostAsync(batchCollection);
    var responsesStatusCodes = await batchResponse.GetResponsesStatusCodesAsync();
    foreach (var response in responsesStatusCodes)
    {
        Console.WriteLine($"Response for drive item {response.Key} with status code {response.Value}");
        if (response.Value != System.Net.HttpStatusCode.NoContent)
        {
            try
            {
                var responseMessage = await batchResponse.GetResponseByIdAsync(response.Key);
                var stringContent = await responseMessage.Content.ReadAsStringAsync();
                var odataError = await KiotaJsonSerializer.DeserializeAsync<ODataError>(stringContent);
                Console.WriteLine($"Error: {odataError.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error: {ex.Message}");
            }
        }
    }
}

If all items in some folder should be deleted, it would be better to delete the whole folder instead of each file one by one.

Upvotes: 1

Related Questions