Дублирование процесса загрузки файлов - Asp.net WebApi - PullRequest
1 голос
/ 27 июня 2019

Я создал веб-API, который позволяет пользователям отправлять файлы и отправлять их в хранилище Azure. Как это работает, клиентское приложение будет подключаться к API для отправки одного или нескольких файлов на контроллер загрузки файлов, а контроллер позаботится об отдыхе, например

  • Загрузка файла в хранилище Azure
  • Обновление базы данных

Прекрасно работает, но я не думаю, что это правильный способ сделать это, потому что теперь я вижу, что есть два разных процесса

  1. Загрузить файл из файловой системы клиента на мой веб-API (сервер)
  2. Загрузка файла в хранилище Azure с API (сервера)

Мне кажется, что я дублирую процесс загрузки, поскольку тот же файл сначала отправляется на API (сервер), а затем на Azure (место назначения) с клиента (файловая система). Я чувствую необходимость показывать клиенту два индикатора выполнения для процесса загрузки файла (с клиента на сервер, а затем с сервера в Azure) - это просто не имеет смысла для меня, и я чувствую, что мой подход неверен.

Мой API принимает до 250 МБ, чтобы вы могли представить перегрузку.

Что вы, ребята, думаете?

//// Контроллер API

if (!Request.Content.IsMimeMultipartContent("form-data"))
   {
    throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
   }

var provider = new RestrictiveMultipartMemoryStreamProvider();
var contents = await Request.Content.ReadAsMultipartAsync(provider);
int Total_Files = contents.Contents.Count();
foreach (HttpContent ctnt in contents.Contents) 
 {
   await storageManager.AddBlob(ctnt)
 }

////// Поток

#region SteamHelper

public class RestrictiveMultipartMemoryStreamProvider : MultipartMemoryStreamProvider
{
    public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
    {
        var extensions = new[] { "pdf", "doc", "docx", "cab", "zip" };
        var filename = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
        if (filename.IndexOf('.') < 0)
            return Stream.Null;

        var extension = filename.Split('.').Last();
        return extensions.Any(i => i.Equals(extension, StringComparison.InvariantCultureIgnoreCase))
                   ? base.GetStream(parent, headers)
                   : Stream.Null;
    }
}

#endregion SteamHelper

///// AddBlob

public async Task<string> AddBlob(HttpContent _Payload)
        {
            CloudStorageAccount cloudStorageAccount = KeyVault.AzureStorage.GetConnectionString();
            CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
            CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("SomeContainer");
            cloudBlobContainer.CreateIfNotExists();
            try
            {
                byte[] fileContentBytes = _Payload.ReadAsByteArrayAsync().Result;
                CloudBlockBlob blob = cloudBlobContainer.GetBlockBlobReference("SomeBlob");
                blob.Properties.ContentType = _Payload.Headers.ContentType.MediaType;
                blob.UploadFromByteArray(fileContentBytes, 0, fileContentBytes.Length);
                var B = await blob.CreateSnapshotAsync();
                B.FetchAttributes();
                return "Snapshot ETAG: " + B.Properties.ETag.Replace("\"", "");
            }
            catch (Exception X)
            {
                return ($"Error : " + X.Message);
            }            
        }

1 Ответ

0 голосов
/ 27 июня 2019

Мне кажется, что я дублирую процесс загрузки, когда тот же файл сначала отправляется на API (сервер), а затем на Azure (место назначения) с клиента (файловая система).

Я думаю, ты прав.Одним из возможных решений было бы, чтобы ваш API генерировал Shared Access Signature (SAS) token и возвращал этот токен / URI SAS клиенту всякий раз, когда клиент желает загрузить файл.

Используя этот SAS URI, ваш клиент может напрямую загрузить файл в хранилище Azure, не отправляя его сначала в API.Как только файл успешно загружен клиентом, он может отправить сообщение в API для обновления базы данных.

Подробнее о SAS можно прочитать здесь: https://docs.microsoft.com/en-us/azure/storage/common/storage-dotnet-shared-access-signature-part-1.

Я также написалсообщение в блоге, давно использующее SAS, которое может оказаться полезным: https://gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/.

...