In today’s Microsoft Graph Mailbag post, we’ll use LargeFileUploadTask from the Microsoft Graph SDKs to upload large files.
Please be sure to follow this blog series using https://aka.ms/MSGraphMailbag or with RSS using https://devblogs.microsoft.com/microsoft365dev/tag/MSGraphMailbag.
Introduction
Over the holiday break, I was updating the dotnetcore-console-sample from .Net 5 to .Net 6. After that was successful, I also updated NuGet dependencies in the project. As part of the validation testing, I fork the repo into my own branch and have automated GitHub Actions that perform a simple “dotnet build” on each project. This allows me to easily check for compilation errors/warnings. As luck would have it, I found a compilation warning this time.
Warning message:
warning CS0618: ‘ChunkedUploadProvider’ is obsolete: ‘ChunkedUploadProvider is now deprecated. Please use the LargeFileUploadTask for the upload of large files using an UploadSession.’
For context, the sample in day29-onedrive attempts to upload two files (one is “small” = under 4MB, one is “large” = over 4MB) to SharePoint Online. The warning above is in reference to the latter scenario for a “large” file upload over 4 MB. Previously, the standard process was to use ChunkedUploadProvider to accomplish this upload.
Looking into this further, I found the associated pull request that marked the ChunkedUploadProvider as obsolete. This update was pushed out as part of Microsoft Graph .Net SDK version 4.13, but LargeFileUploadTask has been available for over a year. The new guidance is to use LargeFileUploadTask for uploading large files using an UploadSession.
Solution
Thankfully, we updated the conceptual documentation for Upload large files using the Microsoft Graph SDKs to reflect the new approach. We have samples currently available in C#, Java, and TypeScript. The following is the C# sample for reference.
using (var fileStream = System.IO.File.OpenRead(filePath)) { // Use properties to specify the conflict behavior // in this case, replace var uploadProps = new DriveItemUploadableProperties { ODataType = null, AdditionalData = new Dictionary<string, object> { { "@microsoft.graph.conflictBehavior", "replace" } } }; // Create the upload session // itemPath does not need to be a path to an existing item var uploadSession = await graphClient.Me.Drive.Root .ItemWithPath(itemPath) .CreateUploadSession(uploadProps) .Request() .PostAsync(); // Max slice size must be a multiple of 320 KiB int maxSliceSize = 320 * 1024; var fileUploadTask = new LargeFileUploadTask<DriveItem>(uploadSession, fileStream, maxSliceSize); // Create a callback that is invoked after each slice is uploaded IProgress<long> progress = new Progress<long>(prog => { Console.WriteLine($"Uploaded {prog} bytes of {fileStream.Length} bytes"); }); try { // Upload the file var uploadResult = await fileUploadTask.UploadAsync(progress); if (uploadResult.UploadSucceeded) { // The ItemResponse object in the result represents the // created item. Console.WriteLine($"Upload complete, item ID: {uploadResult.ItemResponse.Id}"); } else { Console.WriteLine("Upload failed"); } } catch (ServiceException ex) { Console.WriteLine($"Error uploading: {ex.ToString()}"); } }
After updating the code in dotnetcore-console-sample, file uploads are now using LargeFileUploadTask. You can see a successful execution in the following screenshot from my local development environment.
Conclusion
In this post, we covered updating the dotnetcore-console-sample to use the LargeFileUploadTask for uploading large files when using the Microsoft Graph SDKs. Please ensure you are using the latest guidance. Additionally, validate your code with unit, integration or other tests. Until next time!
Today’s post was written by Brian T. Jackett, Principal PM with the Microsoft Graph Customer and Partner Experience (CPx) team. You can follow Brian on Twitter @BrianTJackett.
@Brian Jackett, are you aware of an equivalent API for Azure storage SDK? If not it would be good to contribute to that SDK and have equivalent APIs.
Good question. I haven’t used the Azure SDKs in some time. I know those teams were re-working the SDKs to a more unified format. I found this doc for uploading files but appears to be uploaded in a single request. Not sure if there are examples for uploading in chunks.
https://docs.microsoft.com/azure/developer/python/azure-sdk-example-storage-use
Here is one sample for uploading asynchronously.
https://docs.microsoft.com/azure/storage/blobs/storage-blob-scalable-app-upload-files?tabs=dotnet