Azure Blob 存储 - 显示上传的图像时出错

Posted

技术标签:

【中文标题】Azure Blob 存储 - 显示上传的图像时出错【英文标题】:Azure blob storage - error displaying uploaded images 【发布时间】:2021-11-18 19:14:51 【问题描述】:

我尝试了很多不同的方法并阅读了很多关于 SO 的答案,但在遇到困难时寻求帮助。

我在 azure 上有一个存储帐户和容器,我正在那里成功上传图像,但由于某种原因,它们似乎已损坏。

如果我直接从容器中下载它们,我无法通过 img 标签访问任何图像,也无法查看它们(在 Windows 照片中)。

我相信我的配置是正确的,公共访问级别 blob(我也尝试过公共访问级别 container)。

容器访问级别

已上传 Blob 的视图

图片未通过我的剃须刀页面上的网址显示

html img 标签

如果我下载并在 Windows 中打开,我也无法查看它

从容器下载的 img

我在下面尝试过的 2 个文件流方法示例

    //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>

【问题讨论】:

您上传的内容类型错误。 我认为问题在于您的上传过程。可以分享一下上传图片的代码吗? 我已经用上传代码更新了我的帖子,在此先感谢 【参考方案1】:

正如 cmets 中所述,问题确实出在您的上传代码上。基本上你正在上传一个零字节文件。这是因为下面的代码行:

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

当您使用FileMode.Create 时,如果文件存在,它将被覆盖。来自文档here

指定操作系统应该创建一个新文件。 如果 文件已经存在,它将被覆盖。这需要写 允许。 FileMode.Create 相当于请求如果 文件不存在,使用 CreateNew;否则,使用截断。如果 文件已经存在但是是一个隐藏文件,一个 抛出 UnauthorizedAccessException 异常。

所以本质上你是用一个零字节文件覆盖你想要上传的文件,然后上传那个零字节文件。

要解决这个问题,请将上面的代码行更改为:

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

之后,您的上传和下载都应该可以正常工作了。

【讨论】:

谢谢Guarav,这很有意义,我真的很兴奋,但它并没有解决问题。我将在问题中发布更多我的代码,以防其他任何内容不正确。非常感谢您到目前为止所花的时间来回答。 更新后的代码遇到了什么问题? 在我做了你建议的改变之后发生了一些非常奇怪的事情,它似乎被保存为某种音频文件,当我打开它时,我可以听到人们在说话。只是让整个事情变得更加奇怪! docs.microsoft.com/en-us/azure/storage/blobs/… 我想我可以试试这个教程,看看 CLI 命令生成的代码是什么样子的 因此,您正在上传一个图像文件,但正在上传一个不同的文件。那正确吗?您可以将您正在上传的本地文件与正在上传的文件进行比较吗?两个一样吗? github.com/Azure-Samples/storage-blob-upload-from-webapp 本教程中的图像控制器基本上为我提供了一个可行的解决方案,我扔掉了大部分代码并重新开始。再次感谢您的帮助:)【参考方案2】:

教程:https://docs.microsoft.com/en-us/azure/storage/blobs/storage-upload-process-images?tabs=dotnet%2Cazure-powershell

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

本教程中的图像控制器基本上为我提供了一个可行的解决方案,我扔掉了大部分代码并重新开始。

这是重要的一点

if (StorageHelper.IsImage(formFile))

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

【讨论】:

以上是关于Azure Blob 存储 - 显示上传的图像时出错的主要内容,如果未能解决你的问题,请参考以下文章

尝试将生成的 pdf 文件上传到 Azure Blob 存储时出现 404 错误

Flutter AZURE BLOB IMAGE UPLOAD - 如何将使用移动相机拍摄的图像上传到 azure blob 存储

将图像上传到 Azure Blob 存储

使用 python 将图像上传到 azure blob 存储

通过直接 URL 浏览时上传到 Azure Blob 存储的图像不可用

如何在我的ASP.NET Core应用程序中显示来自我的Azure Blob存储帐户的图像?