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

Другие вопросы по тегам