Example #1
0
        /// <summary>
        /// Callback used when the BackgroundUploadResponseHandler finishes with an error.
        /// </summary>
        /// <param name="exception">The exception from the BackgroundUploadResponseHandler.</param>
        public void OnError(Exception exception)
        {
            var e = new LiveConnectException(ApiOperation.ApiClientErrorCode,
                                             ResourceHelper.GetString("BackgroundUploadResponseHandlerError"),
                                             exception);

            this.tcs.TrySetException(e);
        }
Example #2
0
        /// <summary>
        /// Called when a BackgroundTransferRequest's TransferStatus is set to Completed.
        /// This method will remove the request from the BackgroundTransferService and convert
        /// the result over to a LiveOperationResult and set it on the TaskCompletionSource.
        /// </summary>
        /// <param name="request"></param>
        private void OnTransferStatusComplete(BackgroundTransferRequest request)
        {
            Debug.Assert(request.TransferStatus == TransferStatus.Completed);
            Debug.Assert(BackgroundTransferHelper.IsUploadRequest(request));

            // Remove the transfer request in order to make room in the queue for more transfers.
            // Transfers are not automatically removed by the system.
            // Cancelled requests have already been removed from the system and cannot be removed twice.
            if (!BackgroundTransferHelper.IsCanceledRequest(request))
            {
                try
                {
                    this.backgroundTransferService.Remove(request);
                }
                catch (Exception exception)
                {
                    this.tcs.TrySetException(new LiveConnectException(
                                                 ApiOperation.ApiClientErrorCode,
                                                 ResourceHelper.GetString("BackgroundTransferServiceRemoveError"),
                                                 exception));
                    return;
                }
            }

            this.OnBackgroundTransferRequestCompleted(request);

            if (request.TransferError != null)
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"),
                                                         request.TransferError);
                this.tcs.TrySetException(exception);
                return;
            }

            if (!BackgroundTransferHelper.IsSuccessfulStatusCode(request.StatusCode))
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"));
                this.tcs.TrySetException(exception);
                return;
            }

            // Once we know we have a *good* upload, we have to send it to the response handler
            // to read it's JSON response body. We are an observer to this class, so it will call us back
            // with its result.
            var responseHandler = new BackgroundUploadResponseHandler(
                request.DownloadLocation,
                this);

            responseHandler.ReadJsonResponseFromDownloadLocation();
        }
        /// <summary>
        /// Called when a BackgroundTransferRequet's TransferStatus is set to Completed.
        /// This method will remove the request from the BackgroundTransferService and call
        /// the LiveOperationEventArgs event handler.
        /// </summary>
        /// <param name="request">request with a TransferStatus that is set to Completed</param>
        private void OnTransferStatusComplete(BackgroundTransferRequest request)
        {
            Debug.Assert(request.TransferStatus == TransferStatus.Completed);
            Debug.Assert(BackgroundTransferHelper.IsDownloadRequest(request));

            this.OnBackgroundTransferRequestCompleted(request);

            // Remove the transfer request in order to make room in the queue for more transfers.
            // Transfers are not automatically removed by the system.
            // Cancelled requests have already been removed from the system and cannot be removed twice.
            if (!BackgroundTransferHelper.IsCanceledRequest(request))
            {
                try
                {
                    this.backgroundTransferService.Remove(request);
                }
                catch (Exception exception)
                {
                    this.tcs.TrySetException(new LiveConnectException(
                                                 ApiOperation.ApiClientErrorCode,
                                                 ResourceHelper.GetString("BackgroundTransferServiceRemoveError"),
                                                 exception));
                    return;
                }
            }

            if (request.TransferError != null)
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"),
                                                         request.TransferError);

                this.tcs.TrySetException(exception);
            }
            else if (!BackgroundTransferHelper.IsSuccessfulStatusCode(request.StatusCode))
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"));
                this.tcs.TrySetException(exception);
            }
            else
            {
                string jsonResponse = string.Format(JsonResponse, request.DownloadLocation.OriginalString.Replace("\\", "\\\\"));
                var    jsonReader   = new JsonReader(jsonResponse);
                var    jsonObject   = jsonReader.ReadValue() as IDictionary <string, object>;
                var    result       = new LiveOperationResult(jsonObject, jsonResponse);

                this.tcs.TrySetResult(result);
            }
        }
Example #4
0
        /// <summary>
        /// Parses a string response body and creates a LiveOperationResult object from it.
        /// </summary>
        internal static LiveOperationResult CreateOperationResultFrom(string responseBody, ApiMethod method)
        {
            if (string.IsNullOrEmpty(responseBody))
            {
                if (method != ApiMethod.Delete)
                {
                    var error = new LiveConnectException(
                        ApiClientErrorCode,
                        ResourceHelper.GetString("NoResponseData"));
                    return(new LiveOperationResult(error, false));
                }

                return(new LiveOperationResult(null, responseBody));
            }

            return(LiveOperationResult.FromResponse(responseBody));
        }
Example #5
0
        /// <summary>
        /// Parses a string response body and creates a LiveOperationResult object from it.
        /// </summary>
        protected LiveOperationResult CreateOperationResultFrom(string responseBody)
        {
            if (string.IsNullOrEmpty(responseBody))
            {
                if (this.Method != ApiMethod.Delete)
                {
                    var error = new LiveConnectException(
                        ApiClientErrorCode,
                        ResourceHelper.GetString("NoResponseData"));
                    return(new LiveOperationResult(error, false));
                }

                return(new LiveOperationResult(new DynamicDictionary(), responseBody));
            }

            return(LiveOperationResult.FromResponse(responseBody));
        }
Example #6
0
        /// <summary>
        /// Process the error response.
        /// </summary>
        private async Task <LiveDownloadOperationResult> ProcessDownloadErrorResponse(Exception exception)
        {
            LiveDownloadOperationResult opResult;

            try
            {
                IInputStream responseStream = this.downloadOp.GetResultStreamAt(0);
                if (responseStream == null)
                {
                    var error = new LiveConnectException(
                        ApiOperation.ApiServerErrorCode,
                        ResourceHelper.GetString("ConnectionError"));
                    opResult = new LiveDownloadOperationResult(error, false);
                }
                else
                {
                    var  reader = new DataReader(responseStream);
                    uint length = await reader.LoadAsync(TailoredDownloadOperation.MaxDownloadResponseLength);

                    Exception error = CreateOperationResultFrom(reader.ReadString(length), this.Method).Error;
                    if (error is FormatException)
                    {
                        // if we cannot understand the error response,
                        // return the exception thrown by the background downloader.
                        error = exception;
                    }

                    opResult = new LiveDownloadOperationResult(error, false);
                }
            }
            catch (COMException exp)
            {
                opResult = new LiveDownloadOperationResult(exp, false);
            }
            catch (FileNotFoundException exp)
            {
                opResult = new LiveDownloadOperationResult(exp, false);
            }

            return(opResult);
        }
Example #7
0
        /// <summary>
        /// Handles the refresh token completed event.  Restarts the operation.
        /// </summary>
        private void OnRefreshTokenOperationCompleted(LiveLoginResult result)
        {
            switch (result.Status)
            {
            case LiveConnectSessionStatus.Connected:
                this.LiveClient.Session = result.Session;
                break;

            case LiveConnectSessionStatus.Unknown:
                // Once we know the user is unknown, we clear the session and fail the operation.
                // On Windows Blue, the user may disconnect the Microsoft account.
                // We ensure we are not allowing app to continue to access user's data after the user disconnects the account.
                this.LiveClient.Session = null;
                var error = new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
                this.OnOperationCompleted(new LiveOperationResult(error, false));
                return;
            }

            // We will attempt to perform the operation even if refresh fails.
            this.InternalExecute();
        }
Example #8
0
        protected override void OnWebResponseReceived(WebResponse response)
        {
            LiveOperationResult opResult = this.CreateOperationResultFrom(response);

            if (opResult.Error != null)
            {
                this.OnOperationCompleted(opResult);
                return;
            }

            string uploadLink = null;

            if (opResult.Result != null && opResult.Result.ContainsKey(UploadLocationKey))
            {
                uploadLink = opResult.Result[UploadLocationKey] as string;
            }

            if (string.IsNullOrEmpty(uploadLink))
            {
                var error = new LiveConnectException(ApiOperation.ApiClientErrorCode,
                                                     ResourceHelper.GetString("NoUploadLinkFound"));
                opResult = new LiveOperationResult(error, false);
            }
            else
            {
                try
                {
                    Uri resourceUploadUrl = this.ConstructUploadUri(uploadLink);

                    opResult = new LiveOperationResult(null, resourceUploadUrl.OriginalString);
                }
                catch (LiveConnectException exp)
                {
                    opResult = new LiveOperationResult(exp, false);
                }
            }

            this.OnOperationCompleted(opResult);
        }
Example #9
0
        /// <summary>
        /// Parses the WebResponse's body and creates a LiveOperationResult object from it.
        /// </summary>
        protected LiveOperationResult CreateOperationResultFrom(WebResponse response)
        {
            LiveOperationResult opResult;

            bool nullResponse = (response == null);

            try
            {
                Stream responseStream = (!nullResponse) ? response.GetResponseStream() : null;
                if (nullResponse || responseStream == null)
                {
                    var error = new LiveConnectException(
                        ApiOperation.ApiClientErrorCode,
                        ResourceHelper.GetString("ConnectionError"));

                    opResult = new LiveOperationResult(error, false);
                }
                else
                {
                    using (var sr = new StreamReader(responseStream))
                    {
                        string rawResult = sr.ReadToEnd();
                        opResult = CreateOperationResultFrom(rawResult, this.Method);
                    }
                }
            }
            finally
            {
                if (!nullResponse)
                {
                    ((IDisposable)response).Dispose();
                }
            }

            return(opResult);
        }
        /// <summary>
        /// Handles the refresh token completed event.  Restarts the operation.
        /// </summary>
        private void OnRefreshTokenOperationCompleted(LiveLoginResult result)
        {
            switch (result.Status)
            {
                case LiveConnectSessionStatus.Connected:
                    this.LiveClient.Session = result.Session;
                    break;
                case LiveConnectSessionStatus.Unknown:
                    // Once we know the user is unknown, we clear the session and fail the operation.
                    // On Windows Blue, the user may disconnect the Microsoft account.
                    // We ensure we are not allowing app to continue to access user's data after the user disconnects the account.
                    this.LiveClient.Session = null;
                    var error = new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
                    this.OnOperationCompleted(new LiveOperationResult(error, false));
                    return;
            }

            // We will attempt to perform the operation even if refresh fails.
            this.InternalExecute();
        }
        /// <summary>
        /// Parses a string response body and creates a LiveOperationResult object from it.
        /// </summary>
        protected LiveOperationResult CreateOperationResultFrom(string responseBody)
        {
            if (string.IsNullOrEmpty(responseBody))
            {
                if (this.Method != ApiMethod.Delete)
                {
                    var error = new LiveConnectException(
                        ApiClientErrorCode, 
                        ResourceHelper.GetString("NoResponseData"));
                    return new LiveOperationResult(error, false);
                }

                return new LiveOperationResult(new DynamicDictionary(), responseBody);
            }

            return LiveOperationResult.FromResponse(responseBody);
        }
        /// <summary>
        /// Parses the WebResponse's body and creates a LiveOperationResult object from it.
        /// </summary>
        protected LiveOperationResult CreateOperationResultFrom(WebResponse response)
        {
            LiveOperationResult opResult;

            bool nullResponse = (response == null);
            try
            {
                Stream responseStream = (!nullResponse) ? response.GetResponseStream() : null;
                if (nullResponse || responseStream == null)
                {
                    var error = new LiveConnectException(
                        ApiOperation.ApiClientErrorCode, 
                        ResourceHelper.GetString("ConnectionError"));

                    opResult = new LiveOperationResult(error, false);
                }
                else
                {
                    using (var sr = new StreamReader(responseStream))
                    {
                        string rawResult = sr.ReadToEnd();
                        opResult = this.CreateOperationResultFrom(rawResult);
                    }
                }
            }
            finally
            {
                if (!nullResponse)
                {
                    ((IDisposable)response).Dispose();
                }
            }

            return opResult;
        }
 /// <summary>
 /// Callback used when the BackgroundUploadResponseHandler finishes with an error.
 /// </summary>
 /// <param name="exception">The exception from the BackgroundUploadResponseHandler.</param>
 public void OnError(Exception exception)
 {
     var e = new LiveConnectException(ApiOperation.ApiClientErrorCode,
                                      ResourceHelper.GetString("BackgroundUploadResponseHandlerError"),
                                      exception);
     this.tcs.TrySetException(e);
 }
Example #14
0
        /// <summary>
        /// Callback used when the BackgroundUploadResponseHandler finishes with an error in the json response.
        /// This method will conver the error result into a LiveCompletedEventArgs and call OnCompleted.
        /// </summary>
        /// <param name="code">The error code from the error.</param>
        /// <param name="message">The error message from the error.</param>
        public void OnErrorResponse(string code, string message)
        {
            var exception = new LiveConnectException(code, message);

            this.tcs.TrySetException(exception);
        }
 /// <summary>
 /// Callback used when the BackgroundUploadResponseHandler finishes with an error in the json response.
 /// This method will conver the error result into a LiveCompletedEventArgs and call OnCompleted.
 /// </summary>
 /// <param name="code">The error code from the error.</param>
 /// <param name="message">The error message from the error.</param>
 public void OnErrorResponse(string code, string message)
 {
     var exception = new LiveConnectException(code, message);
     this.tcs.TrySetException(exception);
 }
        /// <summary>
        /// Called when a BackgroundTransferRequest's TransferStatus is set to Completed.
        /// This method will remove the request from the BackgroundTransferService and convert
        /// the result over to a LiveOperationResult and set it on the TaskCompletionSource.
        /// </summary>
        /// <param name="request"></param>
        private void OnTransferStatusComplete(BackgroundTransferRequest request)
        {
            Debug.Assert(request.TransferStatus == TransferStatus.Completed);
            Debug.Assert(BackgroundTransferHelper.IsUploadRequest(request));

            // Remove the transfer request in order to make room in the queue for more transfers.
            // Transfers are not automatically removed by the system.
            // Cancelled requests have already been removed from the system and cannot be removed twice.
            if (!BackgroundTransferHelper.IsCanceledRequest(request))
            {
                try
                {
                    this.backgroundTransferService.Remove(request);
                }
                catch (Exception exception)
                {
                    this.tcs.TrySetException(new LiveConnectException(
                        ApiOperation.ApiClientErrorCode,
                        ResourceHelper.GetString("BackgroundTransferServiceRemoveError"),
                        exception));
                    return;
                }
            }

            this.OnBackgroundTransferRequestCompleted(request);

            if (request.TransferError != null)
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"),
                                                         request.TransferError);
                this.tcs.TrySetException(exception);
                return;
            }

            if (!BackgroundTransferHelper.IsSuccessfulStatusCode(request.StatusCode))
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"));
                this.tcs.TrySetException(exception);
                return;
            }

            // Once we know we have a *good* upload, we have to send it to the response handler
            // to read it's JSON response body. We are an observer to this class, so it will call us back
            // with its result.
            var responseHandler = new BackgroundUploadResponseHandler(
                request.DownloadLocation,
                this);
            responseHandler.ReadJsonResponseFromDownloadLocation();
        }
        private async void OnGetUploadLinkCompleted(LiveOperationResult result)
        {
            if (this.Status == OperationStatus.Cancelled)
            {
                base.OnCancel();
                return;
            }

            if (result.Error != null || result.IsCancelled)
            {
                this.OnOperationCompleted(result);
                return;
            }

            var uploadUrl = new Uri(result.RawResult, UriKind.Absolute);

            // NOTE: the GetUploadLinkOperation will return a uri with the overwite, suppress_response_codes,
            // and suppress_redirect query parameters set.
            Debug.Assert(uploadUrl.Query != null);
            Debug.Assert(uploadUrl.Query.Contains(QueryParameters.Overwrite));
            Debug.Assert(uploadUrl.Query.Contains(QueryParameters.SuppressRedirects));
            Debug.Assert(uploadUrl.Query.Contains(QueryParameters.SuppressResponseCodes));

            var uploader = new BT.BackgroundUploader();
            uploader.Group = LiveConnectClient.LiveSDKUploadGroup;
            if (this.LiveClient.Session != null)
            {
                uploader.SetRequestHeader(
                    ApiOperation.AuthorizationHeader,
                    AuthConstants.BearerTokenType + " " + this.LiveClient.Session.AccessToken);
            }
            uploader.SetRequestHeader(ApiOperation.LibraryHeader, Platform.GetLibraryHeaderValue());
            uploader.Method = HttpMethods.Put;

            this.uploadOpCts = new CancellationTokenSource();
            Exception webError = null;

            LiveOperationResult opResult = null;
            try
            {
                if (this.InputStream != null)
                {
                    this.uploadOp = await uploader.CreateUploadFromStreamAsync(uploadUrl, this.InputStream);
                }
                else
                {
                    this.uploadOp = uploader.CreateUpload(uploadUrl, this.InputFile);
                }

                var progressHandler = new Progress<BT.UploadOperation>(this.OnUploadProgress);

                this.uploadOp = await this.uploadOp.StartAsync().AsTask(this.uploadOpCts.Token, progressHandler);
            }
            catch (TaskCanceledException exception)
            {
                opResult = new LiveOperationResult(exception, true);
            }
            catch (Exception exp)
            {
                // This might be an server error. We will read the response to determine the error message.
                webError = exp;
            }

            if (opResult == null)
            {
                try
                {
                    IInputStream responseStream = this.uploadOp.GetResultStreamAt(0);
                    if (responseStream == null)
                    {
                        var error = new LiveConnectException(
                            ApiOperation.ApiClientErrorCode,
                            ResourceHelper.GetString("ConnectionError"));
                        opResult = new LiveOperationResult(error, false);
                    }
                    else
                    {
                        var reader = new DataReader(responseStream);
                        uint length = await reader.LoadAsync(MaxUploadResponseLength);
                        opResult = ApiOperation.CreateOperationResultFrom(reader.ReadString(length), ApiMethod.Upload);

                        if (webError != null && opResult.Error != null && !(opResult.Error is LiveConnectException))
                        {
                            // If the error did not come from the api service,
                            // we'll just return the error thrown by the uploader.
                            opResult = new LiveOperationResult(webError, false);
                        }
                    }
                }
                catch (COMException exp)
                {
                    opResult = new LiveOperationResult(exp, false);
                }
                catch (FileNotFoundException exp)
                {
                    opResult = new LiveOperationResult(exp, false);
                }
            }

            this.OnOperationCompleted(opResult);
        }
Example #18
0
 private static void ValidateError(LiveConnectException error, string expectedCode)
 {
     Assert.IsTrue(error.ErrorCode.Equals(expectedCode, StringComparison.Ordinal), "Unexpected error code.  Expect: " + expectedCode + " Actual: " + error.ErrorCode);
     Assert.IsTrue(!string.IsNullOrEmpty(error.Message));
 }
        /// <summary>
        /// Parses a string response body and creates a LiveOperationResult object from it.
        /// </summary>
        internal static LiveOperationResult CreateOperationResultFrom(string responseBody, ApiMethod method)
        {
            if (string.IsNullOrEmpty(responseBody))
            {
                if (method != ApiMethod.Delete)
                {
                    var error = new LiveConnectException(
                        ApiClientErrorCode, 
                        ResourceHelper.GetString("NoResponseData"));
                    return new LiveOperationResult(error, false);
                }

                return new LiveOperationResult(null, responseBody);
            }

            return LiveOperationResult.FromResponse(responseBody);
        }
        /// <summary>
        /// Process the error response.
        /// </summary>
        private async Task<LiveDownloadOperationResult> ProcessDownloadErrorResponse(Exception exception)
        {
            LiveDownloadOperationResult opResult;
            try
            {
                IInputStream responseStream = this.downloadOp.GetResultStreamAt(0);
                if (responseStream == null)
                {
                    var error = new LiveConnectException(
                        ApiOperation.ApiServerErrorCode,
                        ResourceHelper.GetString("ConnectionError"));
                    opResult = new LiveDownloadOperationResult(error, false);
                }
                else
                {
                    var reader = new DataReader(responseStream);
                    uint length = await reader.LoadAsync(TailoredDownloadOperation.MaxDownloadResponseLength);
                    Exception error = CreateOperationResultFrom(reader.ReadString(length), this.Method).Error;
                    if (error is FormatException)
                    {
                        // if we cannot understand the error response,
                        // return the exception thrown by the background downloader.
                        error = exception;
                    }

                    opResult = new LiveDownloadOperationResult(error, false);
                }
            }
            catch (COMException exp)
            {
                opResult = new LiveDownloadOperationResult(exp, false);
            }
            catch (FileNotFoundException exp)
            {
                opResult = new LiveDownloadOperationResult(exp, false);
            }

            return opResult;
        }
        /// <summary>
        /// Called when a BackgroundTransferRequet's TransferStatus is set to Completed.
        /// This method will remove the request from the BackgroundTransferService and call
        /// the LiveOperationEventArgs event handler.
        /// </summary>
        /// <param name="request">request with a TransferStatus that is set to Completed</param>
        private void OnTransferStatusComplete(BackgroundTransferRequest request)
        {
            Debug.Assert(request.TransferStatus == TransferStatus.Completed);
            Debug.Assert(BackgroundTransferHelper.IsDownloadRequest(request));

            this.OnBackgroundTransferRequestCompleted(request);

            // Remove the transfer request in order to make room in the queue for more transfers.
            // Transfers are not automatically removed by the system.
            // Cancelled requests have already been removed from the system and cannot be removed twice.
            if (!BackgroundTransferHelper.IsCanceledRequest(request))
            {
                try
                {
                    this.backgroundTransferService.Remove(request);
                }
                catch (Exception exception)
                {
                    this.tcs.TrySetException(new LiveConnectException(
                        ApiOperation.ApiClientErrorCode,
                        ResourceHelper.GetString("BackgroundTransferServiceRemoveError"),
                        exception));
                    return;
                }
            }

            if (request.TransferError != null)
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"),
                                                         request.TransferError);

                this.tcs.TrySetException(exception);
            }
            else if (!BackgroundTransferHelper.IsSuccessfulStatusCode(request.StatusCode))
            {
                var exception = new LiveConnectException(ApiOperation.ApiServerErrorCode,
                                                         ResourceHelper.GetString("ServerError"));
                this.tcs.TrySetException(exception);
            }
            else
            {
                string jsonResponse = string.Format(JsonResponse, request.DownloadLocation.OriginalString.Replace("\\", "\\\\"));
                var jsonReader = new JsonReader(jsonResponse);
                var jsonObject = jsonReader.ReadValue() as IDictionary<string, object>;
                var result = new LiveOperationResult(jsonObject, jsonResponse);

                this.tcs.TrySetResult(result);
            }
        }
        private async void OnGetUploadLinkCompleted(LiveOperationResult result)
        {
            if (this.Status == OperationStatus.Cancelled)
            {
                base.OnCancel();
                return;
            }

            if (result.Error != null || result.IsCancelled)
            {
                this.OnOperationCompleted(result);
                return;
            }

            var uploadUrl = new Uri(result.RawResult, UriKind.Absolute);

            // NOTE: the GetUploadLinkOperation will return a uri with the overwite, suppress_response_codes,
            // and suppress_redirect query parameters set.
            Debug.Assert(uploadUrl.Query != null);
            Debug.Assert(uploadUrl.Query.Contains(QueryParameters.Overwrite));
            Debug.Assert(uploadUrl.Query.Contains(QueryParameters.SuppressRedirects));
            Debug.Assert(uploadUrl.Query.Contains(QueryParameters.SuppressResponseCodes));

            var uploader = new BT.BackgroundUploader();

            uploader.Group = LiveConnectClient.LiveSDKUploadGroup;
            if (this.LiveClient.Session != null)
            {
                uploader.SetRequestHeader(
                    ApiOperation.AuthorizationHeader,
                    AuthConstants.BearerTokenType + " " + this.LiveClient.Session.AccessToken);
            }
            uploader.SetRequestHeader(ApiOperation.LibraryHeader, Platform.GetLibraryHeaderValue());
            uploader.Method = HttpMethods.Put;

            this.uploadOpCts = new CancellationTokenSource();
            Exception webError = null;

            LiveOperationResult opResult = null;

            try
            {
                if (this.InputStream != null)
                {
                    this.uploadOp = await uploader.CreateUploadFromStreamAsync(uploadUrl, this.InputStream);
                }
                else
                {
                    this.uploadOp = uploader.CreateUpload(uploadUrl, this.InputFile);
                }

                var progressHandler = new Progress <BT.UploadOperation>(this.OnUploadProgress);

                this.uploadOp = await this.uploadOp.StartAsync().AsTask(this.uploadOpCts.Token, progressHandler);
            }
            catch (TaskCanceledException exception)
            {
                opResult = new LiveOperationResult(exception, true);
            }
            catch (Exception exp)
            {
                // This might be an server error. We will read the response to determine the error message.
                webError = exp;
            }

            if (opResult == null)
            {
                try
                {
                    IInputStream responseStream = this.uploadOp.GetResultStreamAt(0);
                    if (responseStream == null)
                    {
                        var error = new LiveConnectException(
                            ApiOperation.ApiClientErrorCode,
                            ResourceHelper.GetString("ConnectionError"));
                        opResult = new LiveOperationResult(error, false);
                    }
                    else
                    {
                        var  reader = new DataReader(responseStream);
                        uint length = await reader.LoadAsync(MaxUploadResponseLength);

                        opResult = this.CreateOperationResultFrom(reader.ReadString(length));

                        if (webError != null && opResult.Error != null && !(opResult.Error is LiveConnectException))
                        {
                            // If the error did not come from the api service,
                            // we'll just return the error thrown by the uploader.
                            opResult = new LiveOperationResult(webError, false);
                        }
                    }
                }
                catch (COMException exp)
                {
                    opResult = new LiveOperationResult(exp, false);
                }
                catch (FileNotFoundException exp)
                {
                    opResult = new LiveOperationResult(exp, false);
                }
            }

            this.OnOperationCompleted(opResult);
        }
        protected override void OnWebResponseReceived(WebResponse response)
        {
            // We are done with the HttpWebRequest so let's remove our reference to it.
            // If we hold on to it and Cancel is called, our parent class, WebOperation, will call this.Request.Abort
            // and this causes a Deadlock in the stream.BeginRead call in StreamCopyOperation. Not fun.
            this.Request = null;

            HttpStatusCode status = ((HttpWebResponse)response).StatusCode;
            if (status != HttpStatusCode.OK)
            {
                var result = this.CreateOperationResultFrom(response);
                if (result.Error is FormatException)
                {
                    // We do expect non-JSON errors from other data providers for download requests.
                    // If we can't understand the response body, we'll just return a generic error message.
                    var error = new LiveConnectException(
                        ApiOperation.ApiServerErrorCode,
                        string.Format(
                            CultureInfo.CurrentUICulture,
                            ResourceHelper.GetString("ServerErrorWithStatus"),
                            status.ToString()));

                    result = new LiveOperationResult(error, false);
                }

                this.CompleteOperation(result.Error);
            }
            else if (((HttpWebResponse)response).StatusCode != HttpStatusCode.OK)
            {
                var result = this.CreateOperationResultFrom(response);
                this.CompleteOperation(result.Error);
            }
            else
            {
                this.response = response;
                Stream responseStream = this.response.GetResponseStream();
                this.outputStream = new MemoryStream();
                long totalBytesToReceive;
                string contentLength = response.Headers[DownloadOperation.HttpHeaderContentLength];
                if (!string.IsNullOrEmpty(contentLength))
                {
                    if (!long.TryParse(contentLength, out totalBytesToReceive))
                    {
                        totalBytesToReceive = DownloadOperation.UnknownFileSize;
                    }
                }
                else
                {
                    totalBytesToReceive = DownloadOperation.UnknownFileSize;
                }

                this.streamCopyOperation = new StreamCopyOperation(
                        this.LiveClient,
                        ApiMethod.Download,
                        responseStream,
                        this.outputStream,
                        totalBytesToReceive,
                        this.progress,
                        this.Dispatcher,
                        (isCancelled, error) =>
                        {
                            if (isCancelled)
                            {
                                this.Cancel();
                            }

                            this.CompleteOperation(error);
                        });

                Platform.RegisterForCancel(null, this.streamCopyOperation.Cancel);

                this.streamCopyOperation.Execute();
            }
        }
        protected override void OnWebResponseReceived(WebResponse response)
        {
            // We are done with the HttpWebRequest so let's remove our reference to it.
            // If we hold on to it and Cancel is called, our parent class, WebOperation, will call this.Request.Abort
            // and this causes a Deadlock in the stream.BeginRead call in StreamCopyOperation. Not fun.
            this.Request = null;

            HttpStatusCode status = ((HttpWebResponse)response).StatusCode;

            if (status != HttpStatusCode.OK)
            {
                var result = this.CreateOperationResultFrom(response);
                if (result.Error is FormatException)
                {
                    // We do expect non-JSON errors from other data providers for download requests.
                    // If we can't understand the response body, we'll just return a generic error message.
                    var error = new LiveConnectException(
                        ApiOperation.ApiServerErrorCode,
                        string.Format(
                            CultureInfo.CurrentUICulture,
                            ResourceHelper.GetString("ServerErrorWithStatus"),
                            status.ToString()));

                    result = new LiveOperationResult(error, false);
                }

                this.CompleteOperation(result.Error);
            }
            else if (((HttpWebResponse)response).StatusCode != HttpStatusCode.OK)
            {
                var result = this.CreateOperationResultFrom(response);
                this.CompleteOperation(result.Error);
            }
            else
            {
                this.response = response;
                Stream responseStream = this.response.GetResponseStream();
                this.outputStream = new MemoryStream();
                long   totalBytesToReceive;
                string contentLength = response.Headers[DownloadOperation.HttpHeaderContentLength];
                if (!string.IsNullOrEmpty(contentLength))
                {
                    if (!long.TryParse(contentLength, out totalBytesToReceive))
                    {
                        totalBytesToReceive = DownloadOperation.UnknownFileSize;
                    }
                }
                else
                {
                    totalBytesToReceive = DownloadOperation.UnknownFileSize;
                }

                this.streamCopyOperation = new StreamCopyOperation(
                    this.LiveClient,
                    ApiMethod.Download,
                    responseStream,
                    this.outputStream,
                    totalBytesToReceive,
                    this.progress,
                    this.Dispatcher,
                    (isCancelled, error) =>
                {
                    if (isCancelled)
                    {
                        this.Cancel();
                    }

                    this.CompleteOperation(error);
                });

                Platform.RegisterForCancel(null, this.streamCopyOperation.Cancel);

                this.streamCopyOperation.Execute();
            }
        }
        protected override void OnWebResponseReceived(WebResponse response)
        {
            LiveOperationResult opResult = this.CreateOperationResultFrom(response);

            if (opResult.Error != null)
            {
                this.OnOperationCompleted(opResult);
                return;
            }

            string uploadLink = null;
            if (opResult.Result != null && opResult.Result.ContainsKey(UploadLocationKey))
            {
                uploadLink = opResult.Result[UploadLocationKey] as string;
            }

            if (string.IsNullOrEmpty(uploadLink))
            {
                var error = new LiveConnectException(ApiOperation.ApiClientErrorCode,
                                                     ResourceHelper.GetString("NoUploadLinkFound"));
                opResult = new LiveOperationResult(error, false);
            }
            else
            {
                try
                {
                    Uri resourceUploadUrl = this.ConstructUploadUri(uploadLink);

                    opResult = new LiveOperationResult(null, resourceUploadUrl.OriginalString);

                }
                catch (LiveConnectException exp)
                {
                    opResult = new LiveOperationResult(exp, false);
                }
            }

            this.OnOperationCompleted(opResult);
        }