При загрузке большого файла через Postman (из внешнего интерфейса с формой, написанной на php У меня та же проблема), я получаю сообщение об ошибке 502 неверный шлюз из Azure Web App:
502 - веб-сервер получил неверный ответ, выступая в качестве шлюза или прокси-сервера. Проблема со страницей, которую вы ищете, и она не может быть отображена. Когда веб-сервер (действуя в качестве шлюза или прокси-сервера) связался с вышестоящим контент-сервером, он получил неверный ответ от контент-сервера.
Ошибка, которую я вижу в Azure комментариях к приложению:
Microsoft.AspNetCore.Connections.ConnectionResetException: клиент отключился <--- Была предпринята попытка выполнить операцию на несуществующем сетевом соединении. (Исключение из HRESULT: 0x800704CD) </p>
Это происходит при попытке загрузить тестовый файл объемом 2 ГБ. С файлом 1 ГБ он работает нормально, но он должен работать до ~ 5 ГБ.
Я оптимизировал часть, которая записывает потоки файлов в azure хранилище больших двоичных объектов, используя подход блочной записи (кредиты на : https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/azure-blob-storage-part-4-uploading-large-blobs/), но для меня похоже, что соединение закрыто для клиента (в данном случае для почтальона), так как это, похоже, один запрос HTTP POST и базовый сетевой стек Azure (например, балансировщик нагрузки) закрывает соединение, так как это занимает много времени, пока мой API не вернет HTTP 200 OK для запроса HTTP POST.
Верно ли мое предположение? Если да, как можно добиться того, чтобы загрузка с моего внешнего интерфейса (или почтальона) происходила порциями (например, 15 МБ), которые затем могут быть подтверждены API более быстрым способом, чем целые 2 ГБ? Даже создание URL-адреса SAS для загрузки в azure blob и возврата URL-адреса обратно в браузер было бы хорошо, но я не уверен, как легко это можно интегрировать - также есть максимальные размеры блоков afaik, поэтому для 2 ГБ мне, вероятно, потребуется создать несколько блоков. Если это предложение, было бы здорово получить хороший пример здесь, НО также приветствуются другие идеи!
Это важная часть моей конечной точки контроллера API в C#. Net Core 2.2:
[AllowAnonymous]
[HttpPost("DoPost")]
public async Task<IActionResult> InsertFile([FromForm]List<IFormFile> files, [FromForm]string msgTxt)
{
...
// use generated container name
CloudBlobContainer container = blobClient.GetContainerReference(SqlInsertId);
// create container within blob
if (await container.CreateIfNotExistsAsync())
{
await container.SetPermissionsAsync(
new BlobContainerPermissions
{
// PublicAccess = BlobContainerPublicAccessType.Blob
PublicAccess = BlobContainerPublicAccessType.Off
}
);
}
// loop through all files for upload
foreach (var asset in files)
{
if (asset.Length > 0)
{
// replace invalid chars in filename
CleanFileName = String.Empty;
CleanFileName = Utils.ReplaceInvalidChars(asset.FileName);
// get name and upload file
CloudBlockBlob blockBlob = container.GetBlockBlobReference(CleanFileName);
// START of block write approach
//int blockSize = 256 * 1024; //256 kb
//int blockSize = 4096 * 1024; //4MB
int blockSize = 15360 * 1024; //15MB
using (Stream inputStream = asset.OpenReadStream())
{
long fileSize = inputStream.Length;
//block count is the number of blocks + 1 for the last one
int blockCount = (int)((float)fileSize / (float)blockSize) + 1;
//List of block ids; the blocks will be committed in the order of this list
List<string> blockIDs = new List<string>();
//starting block number - 1
int blockNumber = 0;
try
{
int bytesRead = 0; //number of bytes read so far
long bytesLeft = fileSize; //number of bytes left to read and upload
//do until all of the bytes are uploaded
while (bytesLeft > 0)
{
blockNumber++;
int bytesToRead;
if (bytesLeft >= blockSize)
{
//more than one block left, so put up another whole block
bytesToRead = blockSize;
}
else
{
//less than one block left, read the rest of it
bytesToRead = (int)bytesLeft;
}
//create a blockID from the block number, add it to the block ID list
//the block ID is a base64 string
string blockId =
Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("BlockId{0}",
blockNumber.ToString("0000000"))));
blockIDs.Add(blockId);
//set up new buffer with the right size, and read that many bytes into it
byte[] bytes = new byte[bytesToRead];
inputStream.Read(bytes, 0, bytesToRead);
//calculate the MD5 hash of the byte array
string blockHash = Utils.GetMD5HashFromStream(bytes);
//upload the block, provide the hash so Azure can verify it
blockBlob.PutBlock(blockId, new MemoryStream(bytes), blockHash);
//increment/decrement counters
bytesRead += bytesToRead;
bytesLeft -= bytesToRead;
}
//commit the blocks
blockBlob.PutBlockList(blockIDs);
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print("Exception thrown = {0}", ex);
// return BadRequest(ex.StackTrace);
}
}
// END of block write approach
...
И это пример HTTP POST через почтальона:
![postman pic](https://i.stack.imgur.com/eroGe.png)
Я установил maxAllowedContentLength & requestTimeout в web.config для тестирования уже:
requestLimits maxAllowedContentLength = "4294967295"
и
aspNetCore processPath = "% LAUNCHER_PATH%" arguments = "% LAUNCHER_ARGS% "stdoutLogEnabled =" false "stdoutLogFile =". \ logs \ stdout "requestTimeout =" 00:59:59 "hostingModel =" InProcess "