У меня очень простая задача. В моем ASP.NET Core 2 я должен принимать URL-адрес файла от пользователя и повторно отправлять двоичные данные файла на свой внутренний микросервис. Я пытаюсь сделать это без сохранения файла на диске или в памяти. Просто примите фрагмент файла и отправьте его по сети. Я написал этот код
int bytesToRead = 4096;
byte[] buffer = new Byte[bytesToRead];
// getting download stream
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create(fileUrl);
HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();
if (fileReq.ContentLength > 0)
{
fileResp.ContentLength = fileReq.ContentLength;
}
// getting upload stream
var downloadStream = fileResp.GetResponseStream();
HttpWebRequest uploadRequest = HttpWebRequest.CreateHttp("url_to_send_file_data");
uploadRequest.Method = "POST";
uploadRequest.ContentLength = fileResp.ContentLength;
uploadRequest.ContentType = "application/octet-stream";
var uploadStream = await uploadRequest.GetRequestStreamAsync();
int length = 0;
do
{
length = await downloadStream.ReadAsync(buffer, 0, bytesToRead);
await uploadStream.WriteAsync(buffer, 0, length);
await uploadStream.FlushAsync();
}
while (length > 0);
// all file data in uploadStream._buffer so far
uploadStream.Close();
// only in this point request actually start
var result = await uploadRequest.GetResponseAsync();
downloadStream.Close();
Согласно мануалам и статьям, запрос должен запускаться после uploadRequest.GetRequestStream(), и все вызовы uploadStream.WriteAsync() должны записывать данные прямо в сеть. Но на самом деле все данные файла были записаны в uploadStream._buffer и пошли в сеть только после вызова GetResponseAsync().
Я пытался поиграть со свойствами uploadRequest.SendChunked и заголовками HTTP, но мне не повезло.
Будет ли он полезен для любого предложения.
P.S. Да, про using(){} знаю :)





Я не совсем уверен, что вы там делаете, но предполагая, что у вас есть IFormFile из запроса POST, который содержит ваш файл, вы можете просто использовать его поток для передачи запроса с помощью HttpClient:
private async Task SendFileAsync(IFormFile file, HttpClient client)
{
var url = "url_to_send_file_data";
using (var fileStream = file.OpenReadStream())
using (var request = new HttpRequestMessage(HttpMethod.POST, url))
{
request.Content = new StreamContent(fileStream);
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
}
}
Это будет повторно использовать входящий файловый поток напрямую и использовать его для исходящего запроса.