Загрузка BLOB-объектов Azure не работает в основном приложении ASP .Net. - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь загрузить файл в хранилище BLOB-объектов Azure в Asp .Net Core. Кажется, все работает, но файл не загружен. Вот мой фрагмент кода:

        var blobReference = GetBlobReference();
        rawData.Position = 0;

        //  var result = blobReference.UploadFromStreamAsync(rawData);
        var result = blobReference.UploadFromFileAsync("C:\\users\\tjaartb\\Downloads\\DebitOrderMandate.pdf");
        result.GetAwaiter().GetResult();
        var blobPath = blobReference.Uri.ToString();

Что происходит?

Отладчик перешагивает через result.GetAwaiter().GetResult() без исключений. Проверка переменной задачи result после вызова GetResult() показывает, что состояние задачи - RanToCompletion, а свойство исключения - пустое. Мой контейнер BLOB-объектов успешно создан в предыдущем коде, что указывает на успешное подключение к хранилищу BLOB-объектов. GetResult() заканчивается мгновенно, поэтому кажется, что ничего не происходит.

Вещи, которые я проверял

  • rawData - это MemoryStream, который заполняется данными файла. Использование закомментированной строки для загрузки через поток также не удачно.
  • Соединение с Azure работает.
  • Путь к файлу существует.
  • Нет исключений.
  • Единственное, что выводится в моем окне отладки, это Started Thread <ThreadNumber>
  • Ввод неправильного пути в вызове blobReference.UploadFromFileAsync() приводит к FileNotFoundException, как и ожидалось.
  • Я попытался понизить свой проект до netcoreapp2.0 с netcoreapp2.1, но безуспешно.

Ответы [ 4 ]

0 голосов
/ 12 ноября 2018

В .NET Core 2.1 и WindowsAzure.Storage 9.3.2 все методы теперь асинхронные. Если вы не ожидаете всех вызовов асинхронных методов, вы можете получить тихие сбои. Комментарии под вопросом помогли мне понять это.

0 голосов
/ 03 сентября 2018

Добавление префикса / к имени BLOB-объекта приводит к ошибке без вывода сообщений. Файл не загружается вообще. удаление префикса / решило проблему.

0 голосов
/ 15 сентября 2018

следующий код с WindowsAzure.Storage - пакет версии 9.3.1 работает на Asp Net Core 2.1.

public class AzureBlobModel
{
    public string FileName { get; set; }
    public long? FileSize { get; set; }
    public Stream Stream { get; set; }
    public string ContentType { get; set; }
}

public interface IImageStore
{
    Task<string> SaveDocument(Stream documentStream);
    Task<bool> DeleteDocument(string imageId);
    Task<AzureBlobModel> DownloadDocument(string documentId, string fileName);
    string UriFor(string documentId);
}

public class ImageStore : IImageStore
{
    CloudBlobClient blobClient;
    string baseUri = "https://xxxxx.blob.core.windows.net/";

    public ImageStore()
    {
        var credentials = new StorageCredentials("xxxxx accountName xxxxx", "xxxxx keyValue xxxxx");
        blobClient = new CloudBlobClient(new Uri(baseUri), credentials);
    }

    public async Task<string> SaveDocument(Stream documentStream)
    {
        var documentId = Guid.NewGuid().ToString();
        var container = blobClient.GetContainerReference("xxxxx container xxxxx");
        var blob = container.GetBlockBlobReference(documentId);
        await blob.UploadFromStreamAsync(documentStream);
        return documentId;
    }

    public async Task<bool> DeleteDocument(string documentId)
    {
        var container = blobClient.GetContainerReference("xxxxx container xxxxx");
        var blob = container.GetBlockBlobReference(documentId);
        bool blobExisted = await blob.DeleteIfExistsAsync();
        return blobExisted;
    }

    public async Task<AzureBlobModel> DownloadDocument(string documentId, string fileName)
    {
        var container = blobClient.GetContainerReference("xxxxx container xxxxx");
        var blob = container.GetBlockBlobReference(documentId);

        var doc = new AzureBlobModel()
        {
            FileName = fileName,
            Stream = new MemoryStream(),
        };

        doc.Stream = await blob.OpenReadAsync();
        doc.ContentType = blob.Properties.ContentType;
        doc.FileSize = blob.Properties.Length;

        return doc;
    }

    public string UriFor(string documentId)
    {
        var sasPolicy = new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15),
            SharedAccessExpiryTime = DateTime.UtcNow.AddDays(1)
        };

        var container = blobClient.GetContainerReference("xxxxx container xxxxx");
        var blob = container.GetBlockBlobReference(documentId);
        var sas = blob.GetSharedAccessSignature(sasPolicy);
        return $"{baseUri}xxxxx container xxxxx/{documentId}{sas}";
    }
}

public class DocForCreationDto
{
    public IFormFile File { get; set; }

    // other properties ...
}

// On the controller

[HttpPost]
public async Task<IActionResult> Upload([FromForm]DocForCreationDto docForCreationDto)
{
    if (docForCreationDto.File == null || !ModelState.IsValid)
    {
        return new UnprocessableEntityObjectResult(ModelState);
    }

    string documentId = string.Empty;
    using (var stream = docForCreationDto.File.OpenReadStream())
    {
        documentId = await _imageStore.SaveDocument(stream);
    }

    if (documentId != string.Empty)
    {
        // upload ok ...
        //some business logic here ...
        return Ok();
    }

    return BadRequest("xxx error xxx");
}

[HttpGet("{documentId}", Name = "GetDocument")]
public async Task<IActionResult> GetDocument(int documentId)
{
    var doc = await _imageStore.DownloadDocument(documentId, "output filename");

    return File(doc.Stream, doc.ContentType, doc.FileName);
}

// On Startup - ConfigureServices

services.AddSingleton<IImageStore, ImageStore>();
0 голосов
/ 03 сентября 2018

Интерфейс, который я реализую в этом методе, является частью большой экосистемы, которая не имеет асинхронных подписей. Потребовалось бы много усилий для его рефакторинга.

Вы можете использовать Wait() для замены await для реализации асинхронных подписей. См. Следующий код:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connection);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
var cloudBlobContainer = cloudBlobClient.GetContainerReference("containername");
CloudBlockBlob blob = cloudBlobContainer.GetBlockBlobReference("DebitOrderMandate.pdf");
using (var fileStream = System.IO.File.OpenRead("C:\\users\\tjaartb\\Downloads\\DebitOrderMandate.pdf"))
{
    blob.UploadFromStreamAsync(fileStream).Wait();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...