Я создал веб-API, который позволяет пользователям отправлять файлы и отправлять их в хранилище Azure. Как это работает, клиентское приложение будет подключаться к API для отправки одного или нескольких файлов на контроллер загрузки файлов, а контроллер позаботится об отдыхе, например
- Загрузка файла в хранилище Azure
- Обновление базы данных
Прекрасно работает, но я не думаю, что это правильный способ сделать это, потому что теперь я вижу, что есть два разных процесса
- Загрузить файл из файловой системы клиента на мой веб-API (сервер)
- Загрузка файла в хранилище 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);
}
}