Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure Cloud storage SDK UploadFromStreamAsync not working

I am trying to upload files to Azure blob storage in .Net Core 2.1. Below is my code.

IFormFileCollection files = formCollection.Files;

foreach (var file in files)
{
    if (file.Length > 0)
    {
        _azureCloudStorage.UploadContent(cloudBlobContainer, file.OpenReadStream(), file.FileName);
    }
}

UploadContent implementation-

public async void UploadContent(CloudBlobContainer containerReference, Stream contentStream, string blobName)
{
    try
    {
        using (contentStream)
        {
            var blockBlobRef = containerReference.GetBlockBlobReference(blobName);
            //await containerReference.SetPermissionsAsync(new BlobContainerPermissions
            //{
            //    PublicAccess = BlobContainerPublicAccessType.Blob
            //});
            await blockBlobRef.UploadFromStreamAsync(contentStream);
        }
    }
    catch(Exception ex)
    {
        //Error here
    }
}

The code executes with below error-

{System.ObjectDisposedException: Cannot access a closed file. at System.IO.FileStream.get_Position() at Microsoft.AspNetCore.WebUtilities.FileBufferingReadStream.get_Position() at Microsoft.AspNetCore.Http.Internal.ReferenceReadStream.VerifyPosition() at Microsoft.AspNetCore.Http.Internal.ReferenceReadStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) at Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.WriteToAsync[T](Stream stream, Stream toStream, IBufferManager bufferManager, Nullable1 copyLength, Nullable1 maxLength, Boolean calculateMd5, ExecutionState1 executionState, StreamDescriptor streamCopyState, CancellationToken token) in C:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\Common\Core\Util\StreamExtensions.cs:line 301 at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamAsyncHelper(Stream source, Nullable1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, IProgress1 progressHandler, CancellationToken cancellationToken) in C:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\WindowsRuntime\Blob\CloudBlockBlob.cs:line 352 at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamAsyncHelper(Stream source, Nullable1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext, CancellationToken cancellationToken) in C:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\WindowsRuntime\Blob\CloudBlockBlob.cs:line 290 at Common.AzureCloudStorage.UploadContent(CloudBlobContainer containerReference, Stream contentStream, String blobName)

Alternate solution which worked for me: adding to azure blob storage with stream

Any help with this please? Please let me know if I can provide more details.

like image 534
Display name Avatar asked Jul 08 '18 15:07

Display name


3 Answers

My solution was to wait until the task had completed before continuing, e.g.

    private async void SaveAsync(IFormFile file)
    {
        CloudBlockBlob blob = this.blobContainer.GetBlockBlobReference(file.FileName);
        var task = blob.UploadFromStreamAsync(file.OpenReadStream(), file.Length);

        while (task.IsCompleted == false) {
            Thread.Sleep(1000);
        }

    }

Maybe passing in the length helped as well?

like image 93
Steve Smith Avatar answered Oct 05 '22 01:10

Steve Smith


My solution was to include the file length and set the position = 0.

MemoryStream outStr = new MemoryStream();
CloudBlockBlob myBlob = container.GetBlockBlobReference(name);
outStr.Position = 0;
await myBlob.UploadFromStreamAsync(outStr, outStr.Length);
like image 32
rajiv.cla Avatar answered Oct 05 '22 00:10

rajiv.cla


Same problem, few years later (WindowsAzure.Storage version 3.0.3.0, targetFramework net45).
Synchonous UploadFromStream works, UploadFromStreamAsync does not. I would vote up to suspect Azure SDK does'nt hone async versions, rather than sdk usage deficiency. And, I am also a fairly experienced developer - too experienced to stumble now and then over a Microsoft feature which is declared, but doesn't work when scrutinized closer.
The same here for other async methods (e.g. SetPropertiesAsync). I've been debugging my method (below), and was just losing the breakpoint after every *Async method - that's how I've figured this out. And out of curiousity changed the UploadFromStreamAsync => UploadFromStream, and then SetPropertiesAsync to just SetProperties.

    public async Task StoreItem(string filename, MemoryStream content, string contentType, ICloudBlob cloudBlob)
{
    cloudBlob.UploadFromStream(content); //this line works
    //await cloudBlob.UploadFromStreamAsync(content); //doesn't work
    cloudBlob.Properties.ContentType = contentType;
    cloudBlob.SetProperties();
    //await cloudBlob.SetPropertiesAsync(); //doesn't work either
}
like image 35
Valerii Drotenko Avatar answered Oct 05 '22 01:10

Valerii Drotenko