Home > Mobile >  Azure blob storage - error displaying uploaded images
Azure blob storage - error displaying uploaded images

Time:09-29

I've tried lots of different approaches & read lots of answers on SO but reaching out for help with this as I've hit a wall.

I have a storage account & container on azure, I'm successfully uploading images there but for some reason they seem to be corrupting.

I cannot access any image via an img tag nor can I view them (in windows photos) if I download them directly from the container.

I believe I have the correct configuration, public access level blob (I've also tried public access level container).

container access level access level img

view of the uploaded blob azure blob img

The image doesn't display via the url on my razor page

html img tag missing img razor page

Nor am I able to view it if I download & open in windows

downloaded img from container corrupt image

2 examples of filestream approaches I've tried below

    //approach 1   
     
    
        using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
                    {
                        BlobClient blobClient = container.GetBlobClient(fileName);
                        await blobClient.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = "image/jpg" });
                    }
    
    //approach 2
    
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
            {
                container.UploadBlob(attachment.FileName, fileStream);
            }
    
//service
    public async Task<bool> UploadSample(IFormFile attachment)
            {
                var configSection = Configuration.GetSection("AzureBlobStorge");
                var connectionString = configSection.GetSection("ConnectionString").Value;
                var containerName = configSection.GetSection("ContainerName").Value;
    
                string fileName = Path.GetFileName(attachment.FileName);
                string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\images\\profiles", fileName);
    
                BlobContainerClient container = new BlobContainerClient(connectionString, containerName);
    
                container.SetAccessPolicy(PublicAccessType.BlobContainer);
    
                using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
                {
                    container.UploadBlob(attachment.FileName, fileStream);
    
                    //BlobClient blobClient = container.GetBlobClient(fileName);
                    //await blobClient.UploadAsync(fileStream, new BlobHttpHeaders { ContentType = "image/jpg" });
                }
                return true;
            }

//controller
        [HttpPost]
        [ActionName("ProfilePicsAsync")]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> ProfilePicsAsync(Members item)
        {
            try
            {
                IFormFile formFile = HttpContext.Request.Form.Files[0];
                var member = await _cosmosDbService.GetItemAsync(formFile.Name); //Id passed in the formfile object under name
                if (ModelState.IsValid)
                {
                    if (IsAdminUser())
                    {
                        if (formFile != null)
                        {
                            await _blobStorageService.UploadSample(formFile);
                        }
                        return RedirectToAction("Index");
                    }
                    return BadRequest("Not Authorised");
                }
            }
            catch (Exception ex)
            {
                if(ex is BusinessRuleException)
                {
                    return BadRequest(new BusinessRuleException(ex.Message));
                }
            }

//view
<form asp-action="ProfilePicsAsync" asp-controller="Home" method="post" enctype="multipart/form-data">
    @Html.HiddenFor(m => m.Id)
    <p>INPUT</p>
    <input asp-for="Attachment" Name="@Model.Id" />
    <button type="submit" id="btnUpload" class="btn btn-primary">Upload</button>
</form>

CodePudding user response:

As mentioned in the comments, the issue is indeed with your upload code. Basically you're uploading a zero byte file. This is happening because of the following line of code:

using (FileStream fileStream = new FileStream(filePath, FileMode.Create))

When you use FileMode.Create, if the file exists it will be overwritten. From the documentation here:

Specifies that the operating system should create a new file. If the file already exists, it will be overwritten. This requires Write permission. FileMode.Create is equivalent to requesting that if the file does not exist, use CreateNew; otherwise, use Truncate. If the file already exists but is a hidden file, an UnauthorizedAccessException exception is thrown.

So essentially you're overwriting the file you want to upload with a zero byte file and then uploading that zero byte file.

To fix this, please change the above line of code to:

using (FileStream fileStream = new FileStream(filePath, FileMode.Open))

After that both your upload and download should work.

CodePudding user response:

Tutorial: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-upload-process-images?tabs=dotnet,azure-powershell

Repo: https://github.com/Azure-Samples/storage-blob-upload-from-webapp

The images controller in this tutorial basically had a working solution for me, I threw out most of my code & started again.

This was the important bit

if (StorageHelper.IsImage(formFile))
{
    if (formFile.Length > 0)
    {
        using (Stream stream = formFile.OpenReadStream())
        {
            isUploaded = await StorageHelper.UploadFileToStorage(stream, formFile.FileName, storageConfig);
        }
    }
}
  • Related