Search code examples
c#asp.net-mvcmemorystreamimagesharp

MemoryStream throws exception of type InvalidOperationException


I hope that you can help :)

In my MVC.net core 2.2, when debugging a simple:

MemoryStream ms = new MemoryStream();

Right after initialization it gives me a:

ReadTimeout: 'ms.ReadTimeout' threw an exception of type 'System.InvalidOperationException'
WriteTimeout: 'ms.WriteTimeout' threw an exception of type 'System.InvalidOperationException'

Now the solution doesn't crash or anything. But if I inspect the "ms" in Visual Studio, that's what it says.

What I'm trying to do is via SixLabors.ImageSharp do:

IFormFile file = viewModel.File.Image;

using (Image<Rgba32> image = Image.Load(file.OpenReadStream()))
using (var ms = new MemoryStream())
{
    image.Mutate(x => x.Resize(1000, 1000));
    SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder jpegEncoder = 
        new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder();
    jpegEncoder.Quality = 80;

    image.Save(ms, jpegEncoder);

    StorageCredentials storageCredentials = new StorageCredentials("Name", "KeyValue");

    // Create cloudstorage account by passing the storagecredentials
    CloudStorageAccount storageAccount = new CloudStorageAccount(storageCredentials, true);

    // Create the blob client.
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    // Get reference to the blob container by passing the name by reading the value from the configuration (appsettings.json)
    CloudBlobContainer container = blobClient.GetContainerReference("storagefolder");

    // Get the reference to the block blob from the container
    CloudBlockBlob blockBlob = container.GetBlockBlobReference("image.jpg");

    await blockBlob.UploadFromStreamAsync(ms);
}

But the saved stream is empty (when debugging there is values in Capacity, Length and Position. But after uploading it to azure blob storage, the size is 0).

Kind regards Anda Hendriksen


Solution

  • Write operations to a memory stream aren't atomic, they're buffered for efficiency. You'll need to flush the stream first.

    A second issue is, you're starting to copy the memory stream to your output stream, starting from the end of the stream. So, re-position the memory stream to the start.

    So, before writing the stream to your output:

    ms.Flush();
    ms.Position = 0; // or ms.Seek(0, SeekOrigin.Begin);
    

    Then call

    await blockBlob.UploadFromStreamAsync(ms);