HTTP для изображений между клиентом и сервером отправляет пустой поток

#rest #http #blazor #webassembly #asp.net-core-5.0

#rest #http #blazor #веб-сборка #asp.net-core-5.0

Вопрос:

Я пытаюсь отправить поток (содержащий файл изображения) с клиента WASM на внутренний сервер .NET Core 5. В приложении WASM я начинаю с MemoryStream, который содержит данные файла. Чтобы отправить данные, содержащиеся в этом MemoryStream, используя HttpClient.После синхронизации мне, похоже, нужно преобразовать его в объект StreamContent:

 StreamContent streamContent = new StreamContent(imageMemoryStream);
 

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

Затем я использую HttpClient.PostAsync для отправки этого потока на сервер:

 var response = await Http.PostAsync("api/HttpStreamReceiver", streamContent);
 

На стороне сервера у меня есть контроллер, который получает HTTP-сообщения:

 [Route("api/[controller]")]
[ApiController]
public class HttpStreamReceiverController : ControllerBase
{
    [HttpPost]
    public async Task<ActionResult> Get()
    {
        Stream imageStream;
        try
        {
             imageStream = Request.Body;
        }
        catch (Exception)
        {
             return new BadRequestObjectResult("Error saving file");
        }
    }
}

 

Здесь, похоже, этот запрос.Тело пусто. Попытка оценить длину любого запроса.Тело или ImageStream на стороне сервера приводит к системе.Исключение NotSupportedException и

 await imageStream.ReadAsync(buffer);
 

оставляет буфер пустым. Что я здесь делаю не так?

Ответ №1:

Файл изображения не может быть передан через тело, если он не сериализован. Я предлагаю вам использовать MultipartFormDataContent для передачи файла.

Это пример.

 class Program
{
    static async Task Main(string[] args)
    {
        string filePath = @"D:uploadimages1.png";
        HttpClient _httpClient = new HttpClient();
        string _url = "https://localhost:44324/api/HttpStreamReceiver/";
        if (string.IsNullOrWhiteSpace(filePath))
        {
            throw new ArgumentNullException(nameof(filePath));
        }
        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException($"File [{filePath}] not found.");
        }

        //Create form
        using var form = new MultipartFormDataContent();

        FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
        byte[] buffur = new byte[fs.Length];
        BinaryWriter bw = new BinaryWriter(fs);
        bw.Write(buffur);

        //var bytefile = AuthGetFileData(filePath);
        var fileContent = new ByteArrayContent(buffur);
        fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
        form.Add(fileContent, "image", Path.GetFileName(filePath));

        //the other data in form
        var response = await _httpClient.PostAsync($"{_url}", form);
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        
        bw.Close();
    }
}
 

Веб-api.

 [Route("api/[controller]")]
[ApiController]
public class HttpStreamReceiverController: ControllerBase
{
        [HttpPost]
        public async Task<ActionResult> Get(IFormFile image)
        {
            //...
            return Ok("get");
        }
}
 

Результат:

введите описание изображения здесь

Комментарии:

1. Спасибо. Для этого необходимо использовать BinaryReader вместо BinaryWriter. Использование BinaryRighter заполняет массив байтов всеми нулями.

2. Вы можете преобразовать файл в base64. Затем расшифруйте его в api.

3. Да, но я думаю, что вы имели в виду использовать «BinaryReader» вместо «BinaryWriter» в своем ответе. Даже при таком преобразовании данные не отправляются, но если вы замените «BinaryWriter» на «BinaryReader», это сработает.

4. Хорошо, я проверю это.