Search code examples
c#file-uploadmicrosoft-graph-apiasyncfileupload

How to upload more than 4MB in c# using Microsoft Graph API rest calls


I haven't had luck uploading more than 4MB to a OneDrive, I have successfully Created Folder, rename, delete, and even upload a file that is 4MB or less, however uploading something more than 4MB seems to be a little more complicated. I have been trying to understand by looking at this solution How to upload a large document in c# using the Microsoft Graph API rest calls

There are two solutions. The solution with higher votes suggests a lengthy method (however the function "GetChunkRequestResponseAsync" is deprecated, and I haven't been able to find a suitable function to perform the same), and the second solution uses "new LargeFileUpload", however when I put this in my code (Visual Studio), it tells me that only "LargeFileUploadTask < ? > " exists (same function by appearance however has a "Task" at the end. I don't understand what to put "Task < string > ???".

Anyways, I definitely understand that an uploadSession must be Requested:

var uploadSession = await _client.Drive.Items[FolderID]
                    .ItemWithPath(Name)
                    .CreateUploadSession()
                    .Request()
                    .PostAsync();
var maxChunkSize = 320 * 1024; //320 KB chunk sizes 

and it may involve storing data into a byte array such like:

string FilePath = "D:\\MoreThan5MB.txt";
string path = FilePath;//Actual File Location in your hard drive       

byte[] data = System.IO.File.ReadAllBytes(path);  //Stores all data into byte array by name of "data" then "PUT to the root folder

Stream stream = new MemoryStream(data);

But any help and suggestions would be greatly appreciated. If it means anything, here is a link of someone helping me upload less than 4MB: How to upload to OneDrive using Microsoft Graph Api in c# Thanks


Solution

  • Microsoft has made the upload of large files significantly easier, since the posts to the question. I am currently using MS Graph 1.21.0. This code should work with some small adjustments:

        public async Task<DriveItem> UploadToFolder(
            string driveId,
            string folderId,
            string fileLocation,
            string fileName)
        {
            DriveItem resultDriveItem = null;
    
            using (Stream fileStream = new FileStream(
                        fileLocation,
                        FileMode.Open,
                        FileAccess.Read))
            {
                var uploadSession = await _graphServiceClient.Drives[driveId].Items[folderId]
                                        .ItemWithPath(fileName).CreateUploadSession().Request().PostAsync();
    
                int maxSlice = 320 * 1024;
    
                var largeFileUpload = new LargeFileUploadTask<DriveItem>(uploadSession, fileStream, maxSlice);
    
                IProgress<long> progress = new Progress<long>(x =>
                {
                    _logger.LogDebug($"Uploading large file: {x} bytes of {fileStream.Length} bytes already uploaded.");
                });
    
                UploadResult<DriveItem> uploadResult = await largeFileUpload.UploadAsync(progress);
    
                resultDriveItem = uploadResult.ItemResponse;
            }
    
            return resultDriveItem;
        }