Неверный запрос (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