Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

No examples for large file upload #21

Closed
dkonigsberg opened this issue Nov 17, 2015 · 4 comments
Closed

No examples for large file upload #21

dkonigsberg opened this issue Nov 17, 2015 · 4 comments

Comments

@dkonigsberg
Copy link

The previous project (onedrive-explorer-win) had support in its API for large file upload, and the example applications had the ability to use this support.

However, in this newer version of the API, I see neither documentation nor examples that cover the process of doing a large file upload (as described here).

The closest I've seen is a call wrapping the CreateSession request. However, I have not seen anything that covers the actual uploading of file contents, nor a clean way of wrapping up the whole process.

@ginach
Copy link
Contributor

ginach commented Nov 17, 2015

Correct, resumable upload is not supported natively in the SDK yet, we're tracking it for a future release.

If you'd like to implement this before we add support to the SDK, here is an example of how you can do so.

@ericleigh007
Copy link

Though it is great to have the resumable uploads in the SDK, they won't do any good in mobile instances of usage. That's why I had to find a way to get the SDK to work with BackgroundUploader

This example put me in the ballpark for handling async / background uploads. (just the 100MB single variety for now, but can be expanded using CompletionGroup) and a BackgroundTask.
Though there may be other ways to do it, I use the C# SDK (without any changes) to build the request, then use the BackgroundUploader to send it.

Though I didn't need to change the SDK, it was very helpful to have it on GitHub so that I could refer to the source code in attempting to enhance it. Without the source code this probably would have been impossible. Kudos to the OneDrive team for providing it (NOW, if we can just fix the business/marketing team and get back to a market-leading product....). @ginach seems to also have the perfect attitude and capabilities to support the SDK on GitHub. Awesome.

Most of the code below is generously "borrowed" from the BackgroundTransfer example -- see the universal-windows-samples library on GitHub for more info.

        public async static Task<T> UploadPictureSimpleAsync<T>(StorageFile inFile, Action<UploadOperation> progressHandler = null
                                                                                  , Action<UploadOperation> compHandler = null ) where T : Item
        {
            // no escaping needed for photos.  They have simple names
            var tmpUploadPath = "/drive/special/cameraroll:/" + inFile.Name;
            var theStream = await inFile.OpenStreamForReadAsync();

            if ( progressHandler == null )
            {
                // just do the transfer using the stock OneDrive SDK.  We wait for the result here
                return oneDriveClient.ItemWithPath(tmpUploadPath).Content.Request().PutAsync<Item>(theStream) as T;
            }
            else
            {
                // get the OneDriveSDK to do most of the work here. We can get the request back, and set up the background uploader
                // to do the upload for us.
                var req = oneDriveClient.ItemWithPath(tmpUploadPath).Content.Request();
                var httpReq = req.GetHttpRequestMessage();

                BackgroundUploader uploader = new BackgroundUploader();

                // Change the method to PUT as per the OneDrive REST API
                uploader.Method = "PUT";
                uploader.SetRequestHeader(Constants.Headers.ConsumerSdkVersionHeaderName,
                    String.Format(Constants.Headers.SdkVersionHeaderValue, "1.0.0.1")); // incomplete here, //.GetType().GetTypeInfo().Assembly.Version));

                var authHdr = @"Bearer " + oneDriveClient.AuthenticationProvider.CurrentAccountSession.AccessToken;
                uploader.SetRequestHeader( @"Authorization", authHdr);

                var upload = uploader.CreateUpload(httpReq.RequestUri, inFile);
                Task t = QueueUploadAsync(upload, progressHandler, compHandler, true);

                return default(T);
            }
        }
        public async static Task QueueUploadAsync(UploadOperation upload, Action<UploadOperation> progHandler, Action<UploadOperation> compHandler, bool start)
        {
            string logString;
            try
            {
                logString = "Running OneDrive upload: " + upload.Guid;

                Progress<UploadOperation> progressCallback = new Progress<UploadOperation>(progHandler);

                if (start)
                {
                    // Start the upload and attach a progress handler.  Awaiting this means it'll return when the upload
                    // completes, BUT if we exit the app, the background transfer will continue
                    await upload.StartAsync().AsTask(cts.Token, progressCallback);
                }
                else
                {
                    // The upload was already running when the application started, re-attach the progress handler.
                    // This call returns when the upload is complete.
                    await upload.AttachAsync().AsTask(cts.Token, progressCallback);
                }

                // in this case, that task was successful, and is complete.
                if (compHandler != null)
                {
                    compHandler(upload);
                }
                else
                {
#if DEBUG
                    ResponseInformation response = upload.GetResponseInformation();

                    logString = String.Format(CultureInfo.CurrentCulture, "Upload {0} Completed, Status Code: {1}", upload.Guid,
                        response.StatusCode);
#endif
                }
            }
            catch (TaskCanceledException)
            {
                logString = "Canceled: " + upload.Guid;
            }
            catch (Exception ex)
            {
                if (!IsExceptionHandled("Error", ex, upload))
                {
                    throw;
                }
            }
        }

        internal static bool IsExceptionHandled(string title, Exception ex, UploadOperation upload = null)
        {
            WebErrorStatus error = BackgroundTransferError.GetStatus(ex.HResult);
            if (error == WebErrorStatus.Unknown)
            {
                return false;
            }

            string logString;
            if (upload == null)
            {
                logString = String.Format(CultureInfo.CurrentCulture, "Error: {0}: {1}", title, error);
            }
            else
            {
                logString = String.Format(CultureInfo.CurrentCulture, "Error: {0} - {1}: {2}", upload.Guid, title,
                    error);
            }

            return true;
        }
        public static bool isOneDriveUpload(string hostname)
        {
            return hostname.Contains("onedrive");
        }

        public static string GetResponsePhotoID(string response)
        {
            Item item = JsonConvert.DeserializeObject<Item>(response);

            Debug.WriteLine(String.Format("New uploaded photo ID is {0}", item.Id));

            return item.Id;
        }
    }

I can't wait to see what others will expand this into.

-e

@nsouren
Copy link

nsouren commented May 27, 2016

Hi, when do you expect SDK to support large file upload?

@baywet
Copy link
Member

baywet commented Oct 2, 2024

Thank you for reaching out and for your patience. This SDK is being officially deprecated. See #259 for more information

@baywet baywet closed this as not planned Won't fix, can't repro, duplicate, stale Oct 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants