Как отобразить изображение из моей Azure учетной записи хранилища BLOB-объектов в моем ASP. NET основном приложении? - PullRequest
0 голосов
/ 02 апреля 2020

Я осмотрелся и, несмотря на то, что я вижу много руководств по загрузке в Azure Blob Storage, кажется, что все они перестают получать ваши данные, как только вы это сделаете. В моем сценарии у меня есть приложение, в котором пользователь может загрузить изображение на автомобиль, когда они его создают, я создал сервис для хранения блобов, который я использую с внедрением зависимостей.

Когда пользователь пытается редактировать автомобиль, я ожидаю, что они увидят детали и связанные изображения. То, с чем я борюсь, это возвращение этого изображения, я почти там думаю, но не уверен, что вернуть мою информацию как.

Вот мой код, начинающийся с формы отправки.

Create

@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. Как вы увидите, я открываю инъекцию зависимостей и затем использую ее в методе Это только для загрузки большого двоичного объекта, и все это работает хорошо, чтобы обеспечить полный контекст моей проблемы.

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-объектов который обрабатывает большую часть этого. Как вы можете видеть, когда идентификатор передается со страницы редактирования, он используется для формирования структуры каталогов на 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 или загрузить его. для отображения? Я немного застрял и не уверен. Хотя структура каталогов работает нормально и находит файл ... Я не знаю, как его использовать.

Ответы [ 2 ]

0 голосов
/ 02 апреля 2020

Как правило, вы вообще не возвращаете URL, вы возвращаете огромный блок байтов, тип контента, говорящий «image / jpeg» (или аналогичный), и это то, что помещается в браузер. Ваше свойство img src просто должно ссылаться на действие контроллера, которое возвращает эти байты.

например, метод контроллера, который возвращает файл без использования stati c обслуживания файлов, встроенного в kestrel:

[ResponseCache(Duration = 1200, Location = ResponseCacheLocation.Client)]
public IActionResult GetImage(int id)
{
    // determine file path from id and then
    return PhysicalFile(path, "image/jpeg");
}

Теперь вы не можете вернуть PhysicalFile, но он только читает байты с диска и возвращает их - то же самое для любого файла, просто измените тип содержимого. Попробуйте FileResult, скопировав возвращенные данные:

return File(bytes, "image/jpeg", fileName);
0 голосов
/ 02 апреля 2020

От MS

Коротко: CloudBlockBlob имеет свойства Uri & StorageUri. Первый напрямую указывает на файл, второй позволяет выбрать основной или seconda dry url.

Не должно быть никаких проблем, если разрешить анонимное чтение ваших BLOB-объектов (настроено на Azure Portal)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...