Skip to content

Conversation

@andrueastman
Copy link
Contributor

@andrueastman andrueastman commented Nov 22, 2019

This PR closes microsoftgraph/msgraph-sdk-dotnet#467

Changes proposed in the pull request

  • This PR proposes the adding of a LargeFileUploadTask to support upload of large files in drive or as message attachments.
  • Task uses the ReadOnSubstream proposed in this PR.
    Essentially, one may perform a large upload by following the steps below.

Using the task

  1. create an upload session (This example doesn't use the service library request builders)
// Create upload session 
// POST /v1.0/drive/items/01KGPRHTV6Y2GOVW7725BZO354PWSELRRZ:/SWEBOKv3.pdf:/microsoft.graph.createUploadSession
string uri = $"https://graph.microsoft.com/v1.0/drive/items/{itemId}:/SWEBOKv3.pdf:/microsoft.graph.createUploadSession";

HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
await graphClient.AuthenticationProvider.AuthenticateRequestAsync(httpRequestMessage);

// Read the session info from the response
var httpResponseMessage = await graphClient.HttpProvider.SendAsync(httpRequestMessage);
var content = await httpResponseMessage.Content.ReadAsStringAsync();
var uploadSession = graphClient.HttpProvider.Serializer.DeserializeObject<UploadSession>(content);
  1. Create the task using the session.
// Create task
var maxSliceSize = 320 * 1024; // 320 KB - Change this to your chunk size. 4MB is the default.
LargeFileUploadTask<DriveItem> largeFileUploadTask = new LargeFileUploadTask<DriveItem>(uploadSession, stream, maxSliceSize);
  1. Create an upload monitor
// Setup the progress monitoring
IProgress<long> progress = new Progress<long>(progress =>
{
    Console.WriteLine($"Uploaded {progress} bytes of {stream.Length} bytes");
});
  1. Upload the file
UploadResult<DriveItem> uploadResult = null;
try
{
    uploadResult = await largeFileUploadTask.UploadAsync(progress);
                    
    if (uploadResult.UploadSucceeded)
    {
        Console.WriteLine($"File Uploaded {uploadResult.ItemResponse.Id}");//Sucessful Upload
    }
}
catch (ServiceException e)
{
    Console.WriteLine(e.Message);
}

FileAttachment support

The same steps can be followed for the FileAttachement upload by first creating an upload session and handing it over to the task as illustrated earlier.

// Create task
var maxSliceSize = 320 * 1024; // 320 KB - Change this to your chunk size. 4MB is the default.
LargeFileUploadTask<FileAttachment> largeFileUploadTask = new LargeFileUploadTask<FileAttachment>(uploadSession, stream, maxSliceSize);

However, the service only returns location URI which can be read off from the result object as follows. follows in step 4 as follows.

UploadResult<FileAttachment> uploadResult = null;
try
{
    uploadResult = await largeFileUploadTask.UploadAsync(progress);
    if (uploadResult.UploadSucceeded)
    {
        Console.WriteLine(uploadResult.Location);//the location of the object
    }
}
catch (ServiceException e)
{
    Console.WriteLine(e.Message);
}

Other links

Notes

This PR can also be tested using the sample at the repository in the following link. It uses this PR as a git submodule.
https://github.com/andrueastman/UploadTest

@andrueastman andrueastman self-assigned this Nov 22, 2019
@andrueastman andrueastman changed the title FileUpload Task - WIP FileUpload Task Nov 22, 2019
@andrueastman andrueastman marked this pull request as ready for review November 22, 2019 14:47
@darrelmiller
Copy link
Contributor

Is there a reason why we want to expose GetUploadSliceRequests() ? I don't see an advantage of exposing this. /cc @MIchaelMainer

Andrew Omondi added 3 commits December 3, 2019 08:48
…ance

- make uplaodsliceRequest and get uploadSlices private
- Makes sure stream used for deserialization is disposed.
@andrueastman
Copy link
Contributor Author

I have updated the PR to :

cc @darrelmiller @peombwa @MIchaelMainer

Copy link
Collaborator

@MIchaelMainer MIchaelMainer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry for the late review.

Andrew Omondi added 3 commits December 4, 2019 10:47
- Fix typos
- Add comments to source
- Make UploadResponseHandler and UploadSliceRequest intenal classes
- Remove unnecessary options from upload requests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File upload task

5 participants