ASPNetCore - загрузка файла через REST
Я использую Insomnia для тестирования API, но то же самое происходит с почтальоном.
Я хочу проверить загрузку файла со следующим контроллером:
public async Task<IActionResult> Post([FromForm]IFormFile File)
Если я установлю запрос как составной запрос:
оно работает.
Однако, если я установлю это как двоичный файл:
Я не знаю, как получить данные. Как это можно сделать?
Кроме того, в сигнатуре метода контроллера, если я изменю [FromForm] на [FromBody], я не получаю данные.
Может кто-нибудь уточнить это для меня?
1 ответ
Как вы уже заметили, используя binary file
опция в Почтальоне / Бессоннице не работает стандартным способом. Существует три способа загрузки файла через RESTful API, и вам нужно выбрать один.
Я включил фрагменты кода, которые считывают содержимое загруженного файла в строку и выводят ее - попробуйте отправить текстовый файл, и вы должны получить содержимое файла в ответе 200.
Загрузка данных формы
Это самый популярный / известный метод загрузки, форматирующий отправляемые вами данные в виде набора пар ключ / значение. Вам обычно нужно указать Content-Type
в multipart/form-data
в запросе, а затем использовать [FromForm]
атрибут в MVC для привязки значений к переменным. Также вы можете использовать встроенный IFormFile
класс для доступа к загруженному файлу.
[HttpPost]
public async Task<IActionResult> PostFormData([FromForm] IFormFile file)
{
using (var sr = new StreamReader(file.OpenReadStream()))
{
var content = await sr.ReadToEndAsync();
return Ok(content);
}
}
Загрузка тела
Вы можете отправить тело в формате, понятном MVC, например, JSON, и встроить файл в него. Обычно содержимое файла кодируется с использованием Base64 или другой кодировки, чтобы предотвратить проблемы кодирования / декодирования символов, особенно если вы отправляете изображения или двоичные данные. Например
{
"file": "MTIz"
}
А потом уточняй [FromBody]
внутри вашего контроллера, и использовать класс для десериализации модели.
[HttpPost]
public IActionResult PostBody([FromBody] UploadModel uploadModel)
{
var bytes = Convert.FromBase64String(uploadModel.File);
var decodedString = Encoding.UTF8.GetString(bytes);
return Ok(decodedString);
}
// ...
public class UploadModel
{
public string File { get; set; }
}
При использовании больших и нетекстовых файлов запрос JSON становится неуклюжим и трудным для чтения.
Двоичный файл
Ключевым моментом здесь является то, что ваш файл является целым запросом. Запрос не содержит никакой дополнительной информации, чтобы помочь MVC связать значения с переменными в вашем коде. Поэтому для доступа к файлу необходимо прочитать Body
в Request
,
[HttpPost]
public async Task<IActionResult> PostBinary()
{
using (var sr = new StreamReader(Request.Body))
{
var body = await sr.ReadToEndAsync();
return Ok(body);
}
}
В дополнение к вышесказанному, в случае преобразования составного файла в base64String вы можете обратиться к следующему:
if (File.Length> 0)
{
using (var ms = new MemoryStream())
{
File.CopyTo(ms);
var fileBytes = ms.ToArray();
string s = Convert.ToBase64String(fileBytes);
}
}
Примечание: я использую этот код для.NET CORE 2.1