【发布时间】:2020-07-14 06:33:35
【问题描述】:
我环顾四周,虽然我可以看到许多关于如何上传到 Azure Blob 存储的指南,但它们似乎都无法在您完成后检索您的数据。在我的场景中,我有一个应用程序,用户可以在创建图像时将图像上传到汽车,我为我的 blob 存储创建了一个服务,我将其用于依赖注入。
当用户尝试编辑汽车时,我希望他们能看到详细信息和相关图像。我正在努力返回该图像,我想我快到了,但不确定将我的信息返回为什么。
这是我从提交表单开始的代码。
创建
@model Car
<div class="row">
<div class="col">
<form asp-action="Create" asp-controller="Car" method="post" enctype="multipart/form-data">
<div class="row">
<div class="col">
<div class="md-form form-group">
<label asp-for="Name"></label>
<input type="text" class="form-control" asp-for="Name" />
</div>
<div class="md-form form-group">
<label asp-for="ImageFile" class="active">Image</label>
<!-- Image Upload-->
<kendo-upload name="ImageFile" show-file-list="true">
</kendo-upload>
</div>
</div>
</div>
<div class="row">
<div class="col">
<hr />
<button type="submit" class="btn btn-success">Submit</button>
<button type="reset" class="btn btn-amber">Reset</button>
</div>
</div>
</form>
</div>
</div>
以下是该 Create 视图的相应方法。正如您将看到的,我打开依赖注入,然后在方法中使用它。这仅用于上传 blob,一切正常,这是为了提供我的问题的完整上下文。
CarController.cs
private readonly ICarService _carService;
private readonly IWebHostEnvironment _env;
private readonly IConfiguration _configuration;
public CarController(
IWebHostEnvironment env,
ICarService carService,
IConfiguration configuration)
{
_carService = carService;
_env = env;
_configuration = configuration;
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(Car car)
{
if (ModelState.IsValid)
{
//
//Create Car First
_carService.InsertCar(car);
//
//Get the id if the car just created
int id = car.Id;
//
//If file data is there, prepare and upload to
//blob storage.
if (car.ImageFile != null)
{
string category = "car";
var fileName = "car-image.jpg";
byte[] fileData = new byte[car.ImageFile.Length];
string mimeType = car.ImageFile.ContentType;
BlobStorageService objBlobService = new BlobStorageService(_configuration.GetConnectionString("AzureStorage"));
car.ImagePath = objBlobService.UploadFileToBlob(
category,
id,
fileName,
fileData,
mimeType);
}
return RedirectToAction(nameof(Index));
}
return View(car);
}
下一部分是我苦苦挣扎的地方。我需要在编辑页面上显示上传的图像。这是我开始编写的方法,它不完整,从现在开始我需要帮助。
编辑
[HttpGet]
public IActionResult Edit(int id)
{
//
//Access the service and pass the car ID to it
BlobStorageService objBlob = new BlobStorageService(_configuration.GetConnectionString("AzureStorage"));
objBlob.GetBlobData(id.ToString());
//
//Get car data from the repository
var data = _carService.GetCar(id);
return View(data);
}
这是我的 blob 存储服务,它可以处理其中的大部分内容。正如您所看到的,当 ID 从编辑页面传递时,它用于在 Azure 上形成目录结构以查找相对图像。我正在返回属性,但这是不对的。
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace MyProject.Services
{
public class BlobStorageService
{
string accessKey = string.Empty;
public BlobStorageService(string endPoint)
{
accessKey = endPoint;
}
public string UploadFileToBlob(string category, int id, string strFileName, byte[] fileData, string fileMimeType)
{
try
{
var _task = Task.Run(() => this.UploadFileToBlobAsync(category, id, strFileName, fileData, fileMimeType));
_task.Wait();
string fileUrl = _task.Result;
return fileUrl;
}
catch (Exception)
{
throw;
}
}
public async void GetBlobData(string id)
{
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(accessKey);
CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
string strContainerName = "uploads";
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(strContainerName);
string pathPrefix = "car/" + id;
CloudBlobDirectory blobDirectory = cloudBlobContainer.GetDirectoryReference(pathPrefix);
// get block blob reference
CloudBlockBlob blockBlob = blobDirectory.GetBlockBlobReference("car-image.jpg");
await blockBlob.FetchAttributesAsync();
}
private async Task<string> UploadFileToBlobAsync(string category, int id, string strFileName, byte[] fileData, string fileMimeType)
{
try
{
string strContainerName = "uploads";
string fileName = category + "/" + id + "/" + strFileName;
CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(accessKey);
CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(strContainerName);
if (await cloudBlobContainer.CreateIfNotExistsAsync().ConfigureAwait(false))
{
await cloudBlobContainer.SetPermissionsAsync(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob }).ConfigureAwait(false);
}
if (fileName != null && fileData != null)
{
CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(fileName);
cloudBlockBlob.Properties.ContentType = fileMimeType;
await cloudBlockBlob.UploadFromByteArrayAsync(fileData, 0, fileData.Length).ConfigureAwait(false);
return cloudBlockBlob.Uri.AbsoluteUri;
}
return "";
}
catch (Exception ex)
{
throw (ex);
}
}
}
}
所以,问题是,你如何返回图片的 URL,以便我可以将它放在 img src 标记中或下载它以显示?我让自己有点卡住了,不确定。虽然目录结构工作正常并且它找到了文件...我不知道如何使用它。
【问题讨论】:
-
blob 容器的 ACL 是私有的还是公有的?
-
他们是公开的
-
在这种情况下,请使用 Андрей Саяпин 提供的答案。基本上,在您的模型中,您应该有一个名为 image url 的属性,并且应该使用 blob 的 URL 进行填充,该 URL 的格式始终为:
https://account.blob.core.windows.net/container/path/to/blob.extension。
标签: c# azure asp.net-core azure-blob-storage