Several API methods support uploading media in addition to a regular body.
In that case, the regular request method is overloaded to get an additional
Stream
to upload.
Overview
For any Stream
you wish to upload, you should use resumable
media upload, which allows streams to be uploaded in smaller chunks.
This is especially useful if you are transferring large files,
and the likelihood of a network interruption or some other transmission
failure is high.
It can also reduce your bandwidth usage in the event of network failures
because you don't have to restart large file uploads from the beginning.
ResumableMediaUpload
Resumable Media Upload has been a feature in the Google API .NET client library since 1.2.0-beta. The Google API-specific libraries contain convenience methods for interacting with this feature.
The resumable media upload protocol is described, for example, on the
media upload page for the Drive API.
The main class of interest is
ResumableUpload
.
In this implementation, the media content is uploaded in chunks.
The default chunk size is 10MB, but you can change it by
setting the ChunkSize
property on the request to any multiple of 256KB.
If a server error is encountered in a request then exponential backoff
policy is used to resend the bytes that were not successfully uploaded.
By default, exponential backoff is enabled for each client request.
You can change the default behavior when you construct
a new service object by changing the
DefaultExponentialBackOffPolicy
property on BaseClientService.Initializer
and/or setting the
HttpClientInitializer
property to your own implementation of IConfigurableHttpClientInitializer
that adds some backoff policy.
The methods that support media upload are identified
in the reference documentation for the API-specific documentation.
For these API methods, convenience Upload
and
UploadAsync
methods are added.
Those methods take a Stream
to upload and its content type as parameters.
Make sure that the position of the stream you upload is 0, otherwise you will receive an error, such as "System.InvalidOperationException: The given header was not found".
Note that due to the behavior of the framework's HttpClient
class, if the upload times out, a TaskCanceledException
is thrown.
If you see this exception, consider manually increasing the Timeout
property in
the client used by your service object.
Sample Code
// Create the service using the client credentials. var service = new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Application_Name" }); using var uploadStream = System.IO.File.OpenRead("Local_File_Name"); // Create the File resource to upload. Google.Apis.Drive.v3.Data.File driveFile = new Google.Apis.Drive.v3.Data.File { Name = "Drive_File_Name" }; // Get the media upload request object. FilesResource.CreateMediaUpload insertRequest = service.Files.Create( driveFile, uploadStream, "image/jpeg"); // Add handlers which will be notified on progress changes and upload completion. // Notification of progress changed will be invoked when the upload was started, // on each upload chunk, and on success or failure. insertRequest.ProgressChanged += Upload_ProgressChanged; insertRequest.ResponseReceived += Upload_ResponseReceived; await insertRequest.UploadAsync(); static void Upload_ProgressChanged(IUploadProgress progress) => Console.WriteLine(progress.Status + " " + progress.BytesSent); static void Upload_ResponseReceived(Google.Apis.Drive.v3.Data.File file) => Console.WriteLine(file.Name + " was uploaded successfully");