Search code examples
azureasp.net-corefilemicrosoft-graph-apimicrosoft-graph-sdks

How to use createUploadSession from Microsoft Graph with an ASP.NET Core Web API


I'm creating an ASP.NET Core Web API and I need to upload files larger than 4 MB to a Sharepoint drive. After researching I found the following endpoint

https://graph.microsoft.com/v1.0/me/drive/root:/{fileName}:/createUploadSession

which is capable of uploading files larger than 4 MB. However, I didn't find any way to use GraphAPI to upload, I'm using version 5.50.0.

EDIT: I managed to find out how to create an UploadSession, and upload a file. However, only works with txt and smaller files, images and bigger files are getting corrupted and not working. Here is the code:

public async Task UploadFileInChunks(string uploadUrl, Stream fileStream)
{
    const int maxChunkSize = 320 * 1024; // 320KB
    var buffer = new byte[maxChunkSize];
    long fileLength = fileStream.Length;
    long totalBytesRead = 0;
    int bytesRead;

    while ((bytesRead = await fileStream.ReadAsync(buffer, 0, maxChunkSize)) > 0)
    {
        var chunkData = new ByteArrayContent(buffer, 0, bytesRead);
        chunkData.Headers.ContentRange = new ContentRangeHeaderValue(totalBytesRead, totalBytesRead + bytesRead - 1, fileLength);

        using (var requestMessage = new HttpRequestMessage(HttpMethod.Put, uploadUrl))
        {
            requestMessage.Content = chunkData;

            var response = await new HttpClient().SendAsync(requestMessage);
            response.EnsureSuccessStatusCode();
        }

        totalBytesRead += bytesRead;
    }
}

public async Task<string?> 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);
    }

    return "File uploaded successfully.";
}

Solution

  • Have you tried to use LargeFileUploadTask? There is an example in the doc:

    https://learn.microsoft.com/en-us/graph/sdks/large-file-upload?view=graph-rest-1.0&tabs=csharp#upload-large-file-to-onedrive