Неверный запрос (400) при публикации IFormFile

У меня есть проект.NET Core API, который имеет простую конечную точку для загрузки файла:

[Route("api/[controller]")]
[ApiController]
public class FilesController : Controller
{
    private IFilesService _filesService { get; set; }

    public FilesController(IFilesService filesService)
    {
        _filesService = filesService;
    }

    [HttpPost]
    public async Task<IActionResult> UploadFile(IFormFile file)
    {
        var model = await _filesService.UploadFile(file);
        return Ok();
    }
}

Я пытался проверить это с помощью Postman, но каждый раз, когда я отправляю файл в конечную точку, я получаю ошибку 400 Bad Request. Моя конечная точка никогда не пострадает.

У меня есть несколько других конечных точек POST, которые прекрасно работают, так что это проблема либо с этой конкретной конечной точкой, либо с Postman. Вот моя установка в Почтальоне:

Я крутил свои колеса, пытаясь выяснить, в чем проблема, но в этом нет ничего особенного, и я слежу за примерами, которые видел в Интернете.

Что я делаю неправильно?

4 ответа

Решение

Я вижу, вы установили [ApiController] атрибут, поэтому я предполагаю, что вы используете ASP.Net Core 2.1.

Если он еще не установлен, попробуйте изменить services.AddMvc() в services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); в Startup.cs.

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

Надеюсь это поможет!

Попробуй это.

[HttpPost]
    public async Task<IActionResult> UploadFile([FromForm]IFormFile file)
    {
        var model = await _filesService.UploadFile(file);
        return Ok();
    }

И удалите атрибут ApiController

У меня была такая же проблема при попытке опубликовать FormFile через AJAX, а не через Form.Submit, но я не смог найти полное решение где-либо в Интернете. Я опубликую здесь свое решение, если кто-то еще наткнется на это.

Моя проблема заключалась в атрибуте [AutoValidateAntiForgeryToken] на контроллере, как упомянул Коул В. в своем комментарии. Похоже, это не та проблема, с которой Стивен столкнулся изначально, но, очевидно, @Html.AntiForgeryToken()создаст скрытое поле формы __RequestVerificationToken с токеном, чтобы оно было опубликовано при отправке. Однако, когда вы пытаетесь опубликовать форму вручную, этого не происходит, и вам придется добавить это поле самостоятельно. Для меня клиентский код выглядел так:

              const formData = new FormData();
        formData.append('file', file);
        formData.append(
            '__RequestVerificationToken',
            $('input[name=__RequestVerificationToken]').val());

        $.ajax({
            cache: false,
            type: 'POST',
            url: 'somePostUrl',
            data: formData,
            contentType: false,
            processData: false
        });

Почтальон будет эквивалентен дополнительной паре ключ / значение, хотя нужно будет найти способ получить фактический токен. В целях тестирования, если у вас нет возможности просто удалить атрибут [AutoValidateAntiForgeryToken], потому что он находится в базовом классе, можно вместо этого добавить [IgnoreAntiforgeryToken] к текущему контроллеру или методу конечной точки.

Надеюсь, это избавит кого-то от головной боли в будущем! Я потратил довольно много времени на это ...

Попробуйте ниже URL в Почтальон клиент

  http://localhost:5001/api/Files/UploadFile
Другие вопросы по тегам