#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. Хорошо, я проверю это.