#azure #.net-core #blob #azure-blob-storage
Вопрос:
Я перепробовал множество различных подходов и прочитал множество ответов на этот вопрос, но, обратившись за помощью в этом, я наткнулся на стену.
У меня есть учетная запись хранения и контейнер в azure, я успешно загружаю туда изображения, но по какой-то причине они кажутся повреждающими.
Я не могу получить доступ к изображениям с помощью тега img и не могу их просматривать (в фотографиях Windows), если загружаю их непосредственно из контейнера.
Я считаю, что у меня правильная конфигурация, большой двоичный объект уровня общего доступа (я также пробовал контейнер уровня общего доступа).
просмотр загруженного большого двоичного объекта
Изображение не отображается по URL-адресу на моей странице razor
Я также не смогу просмотреть его, если скачаю и открою в Windows
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. Вы загружаете его с неправильным типом контента.
2. Я полагаю, что проблема связана с вашим процессом загрузки. Можете ли вы поделиться кодом для загрузки изображения?
3. Я обновил свой пост кодом загрузки, заранее спасибо
Ответ №1:
Как упоминалось в комментариях, проблема действительно связана с вашим кодом загрузки. По сути, вы загружаете файл с нулевым байтом. Это происходит из-за следующей строки кода:
using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
При использовании FileMode.Create
, если файл существует, он будет перезаписан. Из документации here
:
Указывает, что операционная система должна создать новый файл. Если файл уже существует, он будет перезаписан. Для этого требуется разрешение на запись. Файловый режим.Создать эквивалентно запросу о том, чтобы, если файл не существует, использовать CreateNew; в противном случае используйте Усечение. Если файл уже существует, но является скрытым файлом, возникает исключение UnauthorizedAccessException.
Таким образом, по сути, вы перезаписываете файл, который хотите загрузить, файлом с нулевым байтом, а затем загружаете этот файл с нулевым байтом.
Чтобы исправить это, пожалуйста, измените приведенную выше строку кода на:
using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
После этого и ваша загрузка, и загрузка должны работать.
Комментарии:
1. Спасибо Гуарав, это имело смысл, и я был очень взволнован, однако это не решило проблему. Я собираюсь опубликовать больше своего кода в вопросе на случай, если что-то еще покажется неправильным. Я действительно ценю то время, которое вы потратили на то, чтобы ответить до сих пор.
2. С какими проблемами вы сталкиваетесь в своем обновленном коде?
3. Что-то действительно странное произошло после того, как я внес предложенное вами изменение на самом деле, похоже, оно сохраняется в виде какого-то аудиофайла, когда я открыл его, я мог слышать разговоры людей. Просто сделало все это еще более странным! docs.microsoft.com/en-us/azure/storage/blobs/… Я думаю, что мог бы попробовать этот учебник и посмотреть, как выглядит код, сгенерированный командами CLI
4. Таким образом, вы загружаете файл изображения, однако загружается другой файл. Это правда? Можете ли вы сравнить загружаемый локальный файл с загружаемым файлом? Являются ли они оба одинаковыми?
5. 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,azure-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);
}
}
}