internal async Task UploadToBlobAsync(String blobName, System.IO.Stream source)
        {
            var fileUploadRequest = new FileUploadRequest()
            {
                BlobName = blobName
            };

            var fileUploadResponse = await this.httpClientHelper.PostAsync <FileUploadRequest, FileUploadResponse>(
                GetRequestUri(this.deviceId, CommonConstants.BlobUploadPathTemplate, null),
                fileUploadRequest,
                ExceptionHandlingHelper.GetDefaultErrorMapping(),
                null,
                CancellationToken.None).ConfigureAwait(false);

            string putString = String.Format("https://{0}/{1}/{2}{3}",
                                             fileUploadResponse.HostName,
                                             fileUploadResponse.ContainerName,
                                             Uri.EscapeDataString(fileUploadResponse.BlobName), // Pass URL encoded device name and blob name to support special characters
                                             fileUploadResponse.SasToken);

            var notification = new FileUploadNotificationResponse();

            try
            {
                // 2. Use SAS URI to send data to Azure Storage Blob (PUT)
                CloudBlockBlob blob       = new CloudBlockBlob(new Uri(putString));
                var            uploadTask = blob.UploadFromStreamAsync(source);
                await uploadTask.ConfigureAwait(false);

                notification.CorrelationId     = fileUploadResponse.CorrelationId;
                notification.IsSuccess         = uploadTask.IsCompleted;
                notification.StatusCode        = uploadTask.IsCompleted ? 0 : -1;
                notification.StatusDescription = uploadTask.IsCompleted ? null : "Failed to upload to storage.";

                // 3. POST to IoTHub with upload status
                await this.httpClientHelper.PostAsync <FileUploadNotificationResponse>(
                    GetRequestUri(this.deviceId, CommonConstants.BlobUploadStatusPathTemplate + "notifications", null),
                    notification,
                    ExceptionHandlingHelper.GetDefaultErrorMapping(),
                    null,
                    CancellationToken.None).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                // 3. POST to IoTHub with upload status
                notification.IsSuccess         = false;
                notification.StatusCode        = -1;
                notification.StatusDescription = ex.Message;

                await this.httpClientHelper.PostAsync <FileUploadNotificationResponse>(
                    GetRequestUri(this.deviceId, CommonConstants.BlobUploadStatusPathTemplate + "notifications/" + fileUploadResponse.CorrelationId, null),
                    notification,
                    ExceptionHandlingHelper.GetDefaultErrorMapping(),
                    null,
                    CancellationToken.None).ConfigureAwait(false);

                throw ex;
            }
        }
        internal async Task UploadToBlobAsync(String blobName, System.IO.Stream source)
        {
            var fileUploadRequest = new FileUploadRequest()
            {
                BlobName = blobName
            };

            var fileUploadResponse = await this.httpClientHelper.PostAsync<FileUploadRequest, FileUploadResponse>(
            GetRequestUri(this.deviceId, CommonConstants.BlobUploadPathTemplate, null),
            fileUploadRequest,
            ExceptionHandlingHelper.GetDefaultErrorMapping(),
            null,
            CancellationToken.None);

            string putString = String.Format("https://{0}/{1}/{2}{3}",
                fileUploadResponse.HostName,
                fileUploadResponse.ContainerName,
                fileUploadResponse.BlobName,
                fileUploadResponse.SasToken);

            var notification = new FileUploadNotificationResponse();

            try
            {
                // 2. Use SAS URI to send data to Azure Storage Blob (PUT)
                CloudBlockBlob blob = new CloudBlockBlob(new Uri(putString));
                var uploadTask = blob.UploadFromStreamAsync(source);
                await uploadTask;

                notification.CorrelationId = fileUploadResponse.CorrelationId;
                notification.IsSuccess = uploadTask.IsCompleted;
                notification.StatusCode = uploadTask.IsCompleted ? 0 : -1;
                notification.StatusDescription = uploadTask.IsCompleted ? null : "Failed to upload to storage.";

                // 3. POST to IoTHub with upload status
                await this.httpClientHelper.PostAsync<FileUploadNotificationResponse>(
                    GetRequestUri(this.deviceId, CommonConstants.BlobUploadStatusPathTemplate + "notifications", null),
                    notification,
                    ExceptionHandlingHelper.GetDefaultErrorMapping(),
                    null,
                    CancellationToken.None);
            }
            catch (Exception ex)
            {
                // 3. POST to IoTHub with upload status
                notification.IsSuccess = false;
                notification.StatusCode = -1;
                notification.StatusDescription = ex.Message;

                await this.httpClientHelper.PostAsync<FileUploadNotificationResponse>(
                    GetRequestUri(this.deviceId, CommonConstants.BlobUploadStatusPathTemplate + "notifications/" + fileUploadResponse.CorrelationId, null),
                    notification,
                    ExceptionHandlingHelper.GetDefaultErrorMapping(),
                    null,
                    CancellationToken.None);

                throw ex;
            }
        }