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).
The image doesn't display via the url on my razor page
Nor am I able to view it if I download & open in windows
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:
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);
}
}
}